android - without - scrollview recyclerview not scrolling




Role RecyclerView para mostrar o item selecionado no topo (9)

Eu estou procurando uma maneira de rolar um RecyclerView para mostrar o item selecionado no topo.

Em um ListView , consegui fazer isso usando scrollTo(x,y) e obtendo o topo do elemento que precisa ser centralizado.

Algo como:

@Override
public void onItemClick(View v, int pos){
    mylistView.scrollTo(0, v.getTop());
}

O problema é que o RecyclerView retorna um erro ao usar seu método scrollTo

RecyclerView não suporta a rolagem para uma posição absoluta

Como posso rolar um RecyclerView para colocar o item selecionado no topo da visão?


// Scroll item pos

linearLayoutManager.scrollToPositionWithOffset(pos, 0);

Eu não sei porque não encontrei a melhor resposta, mas é realmente simples.

recyclerView.smoothScrollToPosition(position);

Sem erros

Cria animações


No meu caso, meu RecyclerView tem um topo de estofamento como este

<android.support.v7.widget.RecyclerView
     ...
     android:paddingTop="100dp"
     android:clipToPadding="false"
/>

Então, para rolar um item para o topo, eu preciso

recyclerViewLinearLayoutManager.scrollToPositionWithOffset(position, -yourRecyclerView.getPaddingTop());

O que eu fiz para restaurar a posição de rolagem depois de atualizar o botão RecyclerView on clicou:

if (linearLayoutManager != null) {

    index = linearLayoutManager.findFirstVisibleItemPosition();
    View v = linearLayoutManager.getChildAt(0);
    top = (v == null) ? 0 : (v.getTop() - linearLayoutManager.getPaddingTop());
    Log.d("TAG", "visible position " + " " + index);
}

else{
    index = 0;
}

linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.scrollToPositionWithOffset(index, top);

obtendo o deslocamento do primeiro item visível do topo antes de criar o objeto linearLayoutManager e depois de instanciar o objeto scrollToPositionWithOffset do objeto LinearLayoutManager foi chamado.


Se você estiver usando o LinearLayoutManager ou o StaggeredGridLayoutManager, cada um deles terá um método scrollToPositionWithOffset que toma a posição e também o deslocamento do início do item desde o início do RecyclerView, o que parece ser o que você precisa (definir o deslocamento para 0 deve alinhar com o topo).

Por exemplo:

//Scroll item 2 to 20 pixels from the top
linearLayoutManager.scrollToPositionWithOffset(2, 20);

Tente o que funcionou para mim legal!

Crie uma variável private static int displayedposition = 0;

Agora, para a posição do seu RecyclerView na sua atividade.

myRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                LinearLayoutManager llm = (LinearLayoutManager) myRecyclerView.getLayoutManager();


                displayedposition = llm.findFirstVisibleItemPosition();


            }
        });

Coloque esta declaração onde você deseja colocar o site antigo exibido em sua visão.

LinearLayoutManager llm = (LinearLayoutManager) mRecyclerView.getLayoutManager();
        llm.scrollToPositionWithOffset(displayedposition , youList.size());

Bem, é isso, funcionou bem para mim \ o /


apenas chame este método simplesmente:

((LinearLayoutManager)RecyclerView.getLayoutManager()).scrollToPositionWithOffset(yourItemPosition,0);

ao invés de:

RecyclerView.scrollToPosition(yourItemPosition);

mesmo com regulador de velocidade

public class SmoothScrollLinearLayoutManager extends LinearLayoutManager {
private static final float MILLISECONDS_PER_INCH = 110f;
private Context mContext;

public SmoothScrollLinearLayoutManager(Context context,int orientation, boolean reverseLayout) {
    super(context,orientation,reverseLayout);
    mContext = context;
}

@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                   int position) {
    RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext()){
        //This controls the direction in which smoothScroll looks for your view
        @Override
        public PointF computeScrollVectorForPosition(int targetPosition) {
            return new PointF(0, 1);
        }

        //This returns the milliseconds it takes to scroll one pixel.
        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
        }
    };
    smoothScroller.setTargetPosition(position);
    startSmoothScroll(smoothScroller);
}


private class TopSnappedSmoothScroller extends LinearSmoothScroller {
    public TopSnappedSmoothScroller(Context context) {
        super(context);

    }

    @Override
    public PointF computeScrollVectorForPosition(int targetPosition) {
        return SmoothScrollLinearLayoutManager.this
                .computeScrollVectorForPosition(targetPosition);
    }

    @Override
    protected int getVerticalSnapPreference() {
        return SNAP_TO_START;
    }
}
}

If you want to scroll automatic without show scroll motion then you need to write following code:

**=> mRecyclerView.getLayoutManager().scrollToPosition(position);**

If you want to display scroll motion then you need to add following code.
=>Step 1: You need to declare SmoothScroller.

RecyclerView.SmoothScroller smoothScroller = new
                LinearSmoothScroller(this.getApplicationContext()) {
                    @Override
                    protected int getVerticalSnapPreference() {
                        return LinearSmoothScroller.SNAP_TO_START;
                    }
                };

=>step 2: You need to add this code any event you want to perform scroll to specific position.
=>First you need to set target position to SmoothScroller.

**smoothScroller.setTargetPosition(position);**

=>Then you need to set SmoothScroller to LayoutManager.
                        **mRecyclerView.getLayoutManager().startSmoothScroll(smoothScroller);**




android-recyclerview