(Smooth)ScrollToPosition не работает должным образом с RecyclerView

Я использую базовый RecyclerView с GridLayoutManager. Я заметил, что ни smoothScrollToPosition ни scrollToPosition работает правильно.

a) при использовании smoothScrollToPosition Я часто получаю ошибку RecyclerView

"RecyclerView" прошел через целевую позицию при плавной прокрутке."

и RecyclerView прокручивается неправильно (часто он пропускает целевую строку). Это наблюдается в основном, когда я пытаюсь прокрутить до 1-го пункта некоторых row

b) при использовании scrollToPosition это, кажется, вполне нормально работать, но большую часть времени я вижу только 1-й элемент строки, а остальные не отображаются.

можете ли вы дать мне несколько советов, как заставить работать правильно хотя бы один из методов?

Спасибо большое!

6 ответов


наконец-то я смог заставить его работать! LinearLayoutManager.scrollToPositionWithOffset(int, int) сделал свое дело.


у меня также есть такая же проблема, но мне удалось исправить эту проблему, настроив SmoothScroller

пусть пользовательский LayoutManager, как показано ниже

public class CustomLayoutManager extends LinearLayoutManager {
    private static final float MILLISECONDS_PER_INCH = 50f;
    private Context mContext;

    public CustomLayoutManager(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView,
        RecyclerView.State state, final int position) {

        LinearSmoothScroller smoothScroller = 
            new LinearSmoothScroller(mContext) {

            //This controls the direction in which smoothScroll looks
            //for your view
            @Override
            public PointF computeScrollVectorForPosition
            (int targetPosition) {
                return CustomLayoutManager.this
                    .computeScrollVectorForPosition(targetPosition);
            }

            //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);
    }
}

(документация прокомментирована внутри кода, приведенного выше)пожалуйста, установите вышеуказанный LayoutManager в recyerview

CustomLayoutManagerlayoutManager = new CustomLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.smoothScrollToPosition(position);

С помощью пользовательского макета менеджер

scrollToPosition также хорошо работает в моем случае вы можете использовать

recyclerView.scrollToPosition(position)

также, если вы хотите отрегулировать скорость smoothScrollToPosition пожалуйста, переопределите

private static final float MILLISECONDS_PER_INCH = 50f;

в CustomLayoutManager. Поэтому, если мы поставим значение как 1f smoothScrollToPosition будет быстрее, как scrollToPosition.увеличение значения делает задержку и уменьшение сделает скорость прокрутки. Надеюсь, это будет полезно.


в моем случае,

`mRecyclerView.scrollToPosition(10);` 

тоже не работает. Но!--3-->

`mRecyclerView.smoothScrollToPosition(10);` 

отлично работает для меня...


для прокрутки вниз вниз из любой позиции в RecyclerView при нажатии EditText.

edittext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                rv_commentList.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                      rv_commentList.scrollToPosition(rv_commentList.getAdapter().getItemCount() - 1);
                    }
                }, 1000);
            }
        });

попробуйте измерить ширину или высоту элемента и вызвать smoothScrollBy (int dx, int dy).


вызов smoothScroll recyclerView не эффективен, так как сам recyclerView не обрабатывает его макет.

вместо этого следует вызвать метод прокрутки диспетчера макетов.

Это должно выглядеть примерно так

mRecyclerView.getLayoutManager().scrollToPosition(desiredPosition);