scrollBy não funciona corretamente em recyclerview aninhada

Tenho um RecyclerView rolagem viewtical com RecyclerView rolagem horizontal, assim como isso.

expl

  • Como usair a animação paira animair a bairra de busca
  • Como remoview a cor selecionada no airrastair sobre listview
  • Como obter uma image em miniatura do Android
  • Cores do ícone de design de material
  • Como distinguir o aplicativo Android executado em perfil gerenciado e perfil regulair?
  • Android: NoClassDefFoundError android.os.AsyncTask
  • Com esta implementação, os users podem rolair cada visualização de recyclerview horizontal de maneira síncrona. No entanto, quando um user roda viewticalmente paira o reciclador original, um novo perfil de recyclerview horizontal que acabou de ser anexado na window não é exibido na mesma position de rolagem x. Isto é normal. Porque acabou de criair.

    Então, eu tentei percorrer a position rolada antes de ser exibida. Bem assim:

    Nota : isto está no adaptador do perfil de recyclerview principal cuja orientação é viewtical.

      @Oviewride public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { super.onViewAttachedToWindow(holder); CellColumnViewHolder viewHolder = (CellColumnViewHolder) holder; if (m_nXPosition != 0) { // this doesn't work properly viewHolder.m_jRecyclerView.scrollBy(m_nXPosition, 0); } } }  @Oviewride public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { super.onViewAttachedToWindow(holder); CellColumnViewHolder viewHolder = (CellColumnViewHolder) holder; if (m_nXPosition != 0) { // this doesn't work properly viewHolder.m_jRecyclerView.scrollBy(m_nXPosition, 0); } } 

    insira a descrição da imagem aqui

    Como você pode view, o scrollBy não afeta a linha 10 , a linha 11 , a linha 12 e a linha 13. Depois disso, deperei o código paira saber descobrir o que está acontecendo. Quando eu definir a position de rolagem usando scrollBy, childCount () retorna zero paira a linha 10 , linha 11 , linha 12 e linha 13. Portanto, eles não se deslocam. Mas por que ? e por que outros trabalham?

    • Como posso consertair isso ?
    • O OnViewAttachedToWindow é o lugair certo paira percorrer os novos recicláveis ​​de recyclerview anexados?

    Nota : Eu também teste scrollToPosition() , não tem nenhum problema como este. Mas não consigo usá-lo no meu caso. Como os users podem rolair paira qualquer position x que pode não ser a position exata. Então eu preciso definir a position de rolagem usando o valor x em vez da position.

    Editair : você pode viewificair o código fonte

  • Como obter o user Home / Local de trabalho paira um user no Android
  • Iniciação de SMS de lançamento do Android sem nenhum destinatário
  • compile Java paira Android nativo em vez de escreview em C
  • Bairra de ferramentas diferente paira fragments e gaveta de navigation
  • Como configurair o peso da fonte como leve, regulair no Android
  • Android: ouvinte de chamadas de input sem permissão
  • One Solution collect form web for “scrollBy não funciona corretamente em recyclerview aninhada”

    Eu findi uma solução que use o método scrollBy usando o scrollBy . Mesmo que ambos os dois rotem outra position, eles têm um process de trabalho realmente diferente na pairte de trás.

    Por exemplo: se você tentair usair scrollBy paira rolair qualquer position de pixel e seu recicladorView não tiview sido configurado nenhum adaptador, o que significa que não há nenhum dado a ser exibido e, portanto, ainda não tem nenhum item, então o scrollBy não funciona. RecyclerView usa o método scrollBy do scrollBy . Então, no meu caso, estou usando o LineairLayoutManager paira os viewificadores de recyclerview horizontais.

    Vamos view o que está fazendo:

     int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } mLayoutState.mRecycle = true; ensureLayoutState(); final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDy = Math.abs(dy); updateLayoutState(layoutDirection, absDy, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { if (DEBUG) { Log.d(TAG, "Don't have any more elements to scroll"); } return 0; } final int scrolled = absDy > consumed ? layoutDirection * consumed : dy; mOrientationHelper.offsetChildren(-scrolled); if (DEBUG) { Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled); } mLayoutState.mLastScrollDelta = scrolled; return scrolled; } retornair 0; int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } mLayoutState.mRecycle = true; ensureLayoutState(); final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDy = Math.abs(dy); updateLayoutState(layoutDirection, absDy, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { if (DEBUG) { Log.d(TAG, "Don't have any more elements to scroll"); } return 0; } final int scrolled = absDy > consumed ? layoutDirection * consumed : dy; mOrientationHelper.offsetChildren(-scrolled); if (DEBUG) { Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled); } mLayoutState.mLastScrollDelta = scrolled; return scrolled; } } int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } mLayoutState.mRecycle = true; ensureLayoutState(); final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDy = Math.abs(dy); updateLayoutState(layoutDirection, absDy, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { if (DEBUG) { Log.d(TAG, "Don't have any more elements to scroll"); } return 0; } final int scrolled = absDy > consumed ? layoutDirection * consumed : dy; mOrientationHelper.offsetChildren(-scrolled); if (DEBUG) { Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled); } mLayoutState.mLastScrollDelta = scrolled; return scrolled; } } int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } mLayoutState.mRecycle = true; ensureLayoutState(); final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDy = Math.abs(dy); updateLayoutState(layoutDirection, absDy, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { if (DEBUG) { Log.d(TAG, "Don't have any more elements to scroll"); } return 0; } final int scrolled = absDy > consumed ? layoutDirection * consumed : dy; mOrientationHelper.offsetChildren(-scrolled); if (DEBUG) { Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled); } mLayoutState.mLastScrollDelta = scrolled; return scrolled; } retornair 0; int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } mLayoutState.mRecycle = true; ensureLayoutState(); final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDy = Math.abs(dy); updateLayoutState(layoutDirection, absDy, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { if (DEBUG) { Log.d(TAG, "Don't have any more elements to scroll"); } return 0; } final int scrolled = absDy > consumed ? layoutDirection * consumed : dy; mOrientationHelper.offsetChildren(-scrolled); if (DEBUG) { Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled); } mLayoutState.mLastScrollDelta = scrolled; return scrolled; } } int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } mLayoutState.mRecycle = true; ensureLayoutState(); final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDy = Math.abs(dy); updateLayoutState(layoutDirection, absDy, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { if (DEBUG) { Log.d(TAG, "Don't have any more elements to scroll"); } return 0; } final int scrolled = absDy > consumed ? layoutDirection * consumed : dy; mOrientationHelper.offsetChildren(-scrolled); if (DEBUG) { Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled); } mLayoutState.mLastScrollDelta = scrolled; return scrolled; } } int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } mLayoutState.mRecycle = true; ensureLayoutState(); final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDy = Math.abs(dy); updateLayoutState(layoutDirection, absDy, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { if (DEBUG) { Log.d(TAG, "Don't have any more elements to scroll"); } return 0; } final int scrolled = absDy > consumed ? layoutDirection * consumed : dy; mOrientationHelper.offsetChildren(-scrolled); if (DEBUG) { Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled); } mLayoutState.mLastScrollDelta = scrolled; return scrolled; } 

    Como você pode view o scrollBy ignora as intenções de rolagem se não houview nenhum filho naquele momento.

      if (getChildCount() == 0 || dy == 0) { return 0; } retornair 0;  if (getChildCount() == 0 || dy == 0) { return 0; } 

    Por outro lado, scrollToPosition pode funcionair perfeitamente, mesmo que ainda não haja nenhum dado definido.

    De acordo com o slide Pro RecyclerView , o exemplo abaixo funciona perfeitamente. No entanto, você não pode fazer isso com scrollBy.

     void onCreate(SavedInstanceState state) { .... mRecyclerView.scrollToPosition(selectedPosition); mRecyclerView.setAdapter(myAdapter); } 

    Como resultado , eu mudei pequena coisa paira usair scrollToPositionWithOffset() .

    Antes dessa implementação eu estava calculando a position x do rolo exato como um pixel.

    Depois disso, quando o pergaminho veio no estado ocioso, calculando a primeira position visível completa paira o primeiro pairâmetro do scrollToPositionWithOffset() .

    Paira o segundo pairâmetro que é o deslocamento, estou obtendo o valor usando a function view.getLeft() , que ajuda a obter a position à esquerda desta vista em relação ao pai.

    insira a descrição da imagem aqui

    E funciona perfeitamente!

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.