web-dev-qa-db-ja.com

Android:リサイクラービューでのスムーズスクロールの制御

CardViewでRecyclerviewを使用しています。リストビューで速度を制御する方法を知っています。しかし、Recyclerviewではありません。

見つかったクラス名で多くを検索しました SmoothScroll 。使い方は?何も思いつきません!現在、Recyclerviewはデフォルトでスクロールが高速です。

UPDATE:

this でGil Answerを要約しました

49
Shabbir Dhangot

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

次に、スクロールする必要がある距離を計算するには、現在のスクロール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;
    }

Edit:上記の方法では、「getScrollState()」を呼び出します。これはRecyclerViewのメソッドです。この実装では、カスタムLayoutManagerはカスタムRecyclerViewのネストされたクラスです。これがうまくいかない場合は、何らかのインターフェイスパターンを介してスクロール状態を取得しようとすることができます。

3。投げ飛ばし速度を遅くする

ここでは、投げ飛ばし速度を縮小します。 RecyclerViewサブクラス内のflingメソッドをオーバーライドする必要があります。

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

コードを投稿していないか、セットアップに関する多くの情報を提供していないため、よりカスタマイズされたソリューションを提供することは困難ですが、これがほとんどのベースをカバーし、最適なソリューションを見つけるのに役立つことを願っています。

100
Gil Moshayof

Answerを使用して、スムーズスクロールを制御する方法を単純化します。

クラスを作成

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

}

.7を値に置き換えることで速度を調整します。

次に、このクラスをXMLで次のように使用します。

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

JavaのようにRecyclerViewを読んでください。

CustomRecyclerView mRecyclerView;
mRecyclerView = (CustomRecyclerView) findViewById(R.id.my_recycler_view);
32
Shabbir Dhangot

LinearLayoutManagerのsmoothScrollToPosition()を実装するだけです:

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

};
27
Blunderer