web-dev-qa-db-ja.com

選択した項目を一番上に表示するには、RecyclerViewをスクロールします。

選択した項目を一番上に表示するためにRecyclerViewをスクロールする方法を探しています。

ListViewでは、scrollTo(x,y)を使用し、中央揃えする必要がある要素の先頭を取得することで、これを実行できました。

何かのようなもの:

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

問題は、RecyclerViewメソッドを使用しているときにscrollToがエラーを返すことです。

RecyclerViewは絶対位置へのスクロールをサポートしていません

選択した項目をビューの一番上に配置するためにRecyclerViewをスクロールするにはどうすればいいですか?

173
Distwo

LinearLayoutManagerまたはStaggered GridLayoutManagerを使用している場合、それらはそれぞれ、 - RecyclerViewの先頭からの項目の先頭の位置とオフセットの両方を取得する scrollToPositionWithOffset メソッドを持っています。必要(オフセットを0に設定すると上と揃うはずです)。

例えば:

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

あなたが垂直のLinearLayoutマネージャを探しているなら、あなたはカスタムLinearSmoothScrollerを使ってスムーズなスクロールを達成することができます:

import Android.content.Context;
import Android.graphics.PointF;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.LinearSmoothScroller;
import Android.support.v7.widget.RecyclerView;

public class SnappingLinearLayoutManager extends LinearLayoutManager {

    public SnappingLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                       int position) {
        RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

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

        }

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

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

リサイクルビューでlayoutmanagerのインスタンスを使用してからrecyclerView.smoothScrollToPosition(pos);を呼び出すと、選択した位置までスクロールしてリサイクルビューの上に移動できます。

80
nizammoidu

//アイテム位置のスクロール

linearLayoutManager.scrollToPositionWithOffset(pos, 0);
43
HBQ

あなただけのrecyclerview.scrollToPosition(position)を呼び出す必要があります。それはいいです!

アダプタでそれを呼び出したい場合は、メソッドにgetRecyclerview()を実装するのではなく、アダプタにrecyclerviewのインスタンス、またはrecyclerviewを含むアクティビティまたはフラグメントを持たせるだけです。

お役に立てば幸いです。

17
Zero

スピードレギュレータと同じ

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

ボタンをクリックしてRecyclerViewを更新した後にスクロール位置を復元するために私がしたこと:

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

linearLayoutManagerオブジェクトを作成する前とそれをインスタンス化した後の最初の表示項目の上からのオフセットを取得すると、LinearLayoutManagerオブジェクトのscrollToPositionWithOffsetが呼び出されました。

6
tsiro

私のために何がうまくいったか試してみてくださいクール!

変数private static int displayedposition = 0;を作成します

さあ、あなたのアクティビティにおけるあなたのRecyclerViewの位置について。

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


            }
        });

このステートメントを、ビューに表示されている前のサイトを配置する場所に配置します。

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

まあそれはそれだ、それは私のためにうまく働いた\ o /

6
user3740244

特定の位置にスクロールする
そしてこれは私をたくさん助けた。クリックリスナーによって、あなたはあなたのアダプターの位置を得ることができます

layoutmanager.scrollToPosition(int position);
3
Sandeep Singh

私の場合、私のRecyclerViewはこのようなパディングトップを持っています

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

それから項目を上にスクロールするために、私はする必要があります

recyclerViewLinearLayoutManager.scrollToPositionWithOffset(position, -yourRecyclerView.getPaddingTop());
2
Phan Van Linh
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);**
1
Paras Santoki

私はなぜ最良の答えを見つけられなかったのかわかりませんが、それは本当に簡単です。

recyclerView.smoothScrollToPosition(position);

エラーなし

アニメーションを作成します

1
Lucem

単にこのメソッドを呼び出すだけです:

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

の代わりに:

RecyclerView.scrollToPosition(yourItemPosition);