38

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

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

UPDATE:

Я Обобщенная Gil Ответ с this

+0

@XaverKapeller Я хочу осуществить медленный скроллинг в RecyclerView. –

+0

Что вы имеете в виду с медленной прокруткой? Пожалуйста, объясните больше. Вы хотите программно прокрутить до какой-либо другой позиции? –

+0

Все еще не понимаю. Какая скорость прокрутки? О чем ты говоришь? Скорость прокрутки при программном прокрутке в другую позицию? –

ответ

90

Неясно, что вы имеете в виду, когда вы говорите "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. Вы можете найти пример того, как отслеживать прокрутку ресайклера y here.

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

targetScrollY = targetPosition * itemHeight 

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

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

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

3. Замедление скорости Fling

Здесь вы хотите уменьшаем скорость Fling.Вам нужно будет переопределить метод 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); 
} 

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

+0

Я хочу, чтобы прокрутить вниз ручную прокрутку вашей второй точки. Но методы и переменные не определены. можете ли вы обновить это. –

+0

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

+0

ОК, обновляя мой вопрос в минуту. –

26

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

Создание класса

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); 
+2

ничего не делает для меня – Androider

+0

Что вы сделали? как я описал в своем ответе –

+0

Я сделал то же самое. Но каким-то образом установив скорость Y для разных значений (даже 0,1) ничего не делает – Androider

14

Просто реализовать 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); 
    } 

}; 
+0

Это очень помогло мне. Благодарим за сообщение! –

+0

Вы экономите много времени. – abbath0767

+0

Добро пожаловать :) – Blunderer