Подтвердить что ты не робот

Android: Управление Гладкая прокрутка по просмотру ресайклеров

Я использую Recyclerview с CardView. Я знаю, как контролировать скорость просмотра списка. Но не для Recyclerview.

Я много искал в найденном имени класса SmoothScroll. Как это использовать? Понятия не имею! Прямо сейчас Recyclerview по умолчанию прокручивается быстро.

UPDATE:

Я обобщил ответ Гила с этим

4b9b3361

Ответ 1

Непонятно, что вы имеете в виду, когда говорите "smoothScroll". Вы можете ссылаться на автоматический "smoothScrollToPosition", который будет автоматически прокручиваться до указанной позиции, вы могли бы говорить о ручной прокрутке, и вы могли бы говорить о броске. Ради процветания я попытаюсь ответить на все эти вопросы сейчас.

1. Автоматическая плавная прокрутка.

Внутри менеджера компоновки вам необходимо реализовать метод smoothScrollToPosition:

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, State state, int position)
    {
        // A good idea would be to create this instance in some initialization method, and just set the target position in this method.
        LinearSmoothScroller smoothScroller = new LinearSmoothScroller(getContext())
        {
            @Override
            public PointF computeScrollVectorForPosition(int targetPosition)
            {
                int yDelta = calculateCurrentDistanceToPosition(targetPosition);
                return new PointF(0, yDelta);
            }

            // This is the important method. This code will return the amount of time it takes to scroll 1 pixel.
            // This code will request X milliseconds for every Y DP units.
            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics)
            {
                return X / TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, Y, displayMetrics);
            }

        };
        smoothScroller.setTargetPosition(position);

        startSmoothScroll(smoothScroller);
    }

В этом примере я использую вспомогательный метод с именем "calculateCurrentDistanceToPosition". Это может быть немного сложно, поскольку оно включает в себя отслеживание текущей позиции прокрутки и вычисление положения прокрутки заданной позиции y. Вы можете найти пример того, как отслеживать прокрутку recycler y здесь.

Вычисление прокрутки y данной позиции действительно зависит от того, что отображает ваш повторитель. Предполагая, что все ваши элементы имеют одинаковую высоту, вы можете рассчитать это, выполнив следующий расчет:

targetScrollY = targetPosition * itemHeight

Затем, чтобы вычислить расстояние, которое вам нужно прокрутить, просто вычтите текущую прокрутку y с целевой прокруткой y:

private int calculateCurrentDistanceToPosition(int targetPosition) {
    int targetScrollY = targetPosition * itemHeight;
    return targetScrollY - currentScrollY;
}

2. Замедление ручной прокрутки.

Еще раз вам нужно отредактировать менеджер компоновки, на этот раз - метод scrollVerticallyBy:

    @Override
    public int scrollVerticallyBy(int delta, Recycler recycler, State state)
    {
       // write your limiting logic here to prevent the delta from exceeding the limits of your list.

       int prevDelta = delta;
       if (getScrollState() == SCROLL_STATE_DRAGGING)
            delta = (int)(delta > 0 ? Math.max(delta * MANUAL_SCROLL_SLOW_RATIO, 1) : Math.min(delta * MANUAL_SCROLL_SLOW_RATIO, -1));  

       // MANUAL_SCROLL_SLOW_RATIO is between 0 (no manual scrolling) to 1 (normal speed) or more (faster speed).
       // write your scrolling logic code here whereby you move each view by the given delta

        if (getScrollState() == SCROLL_STATE_DRAGGING)
            delta = prevDelta;

        return delta;
    }

Изменить: В приведенном выше методе я вызываю "getScrollState()". Это метод RecyclerView. В этой реализации мой пользовательский LayoutManager является вложенным классом моего пользовательского RecyclerView. Если это не сработает для вас, вы можете попытаться захватить состояние прокрутки через какой-либо шаблон интерфейса.

3. Замедление скорости движения

Здесь вы хотите уменьшить скорость движения. Вам необходимо переопределить метод fling внутри вашего подкласса RecyclerView:

@Override
public boolean fling(int velocityX, int velocityY)
{
     velocityY *= FLING_SCALE_DOWN_FACTOR; // (between 0 for no fling, and 1 for normal fling, or more for faster fling).

     return super.fling(velocityX, velocityY);
}

Мне сложно предоставить более индивидуальное решение, так как вы не опубликовали ни один из своих кодов или не предоставили много информации о своей настройке, но я надеюсь, что это охватывает большинство баз и поможет вам найти лучшее решение для вас.

Ответ 2

Я просто упрощаю Ответ, как использовать его для управления плавным прокруткой.

Создать класс

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;

public class CustomRecyclerView extends RecyclerView {

    Context context;

    public CustomRecyclerView(Context context) {
        super(context);
        this.context = context;
    }

    public CustomRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean fling(int velocityX, int velocityY) {

        velocityY *= 0.7;
        // velocityX *= 0.7; for Horizontal recycler view. comment velocityY line not require for Horizontal Mode.

        return super.fling(velocityX, velocityY);
    }

}

Отрегулируйте скорость, заменив 0,7 на ваше значение.

Теперь используйте этот класс в своем XML, как это.

<<yourpackage>.CustomRecyclerView
    android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

Прочитайте RecyclerView в Java как.

CustomRecyclerView mRecyclerView;
mRecyclerView = (CustomRecyclerView) findViewById(R.id.my_recycler_view);

Ответ 3

Просто реализуйте smoothScrollToPosition() вашего LinearLayoutManager:

LinearLayoutManager layoutManager = new LinearLayoutManager(this) {

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        LinearSmoothScroller smoothScroller = new LinearSmoothScroller(this) {

            private static final float SPEED = 300f;// Change this value (default=25f)

            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                return SPEED / displayMetrics.densityDpi;
            }

        };
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

};