首页 文章

滚动RecyclerView以在顶部显示所选项目

提问于
浏览
160

我正在寻找一种滚动 RecyclerView 以在顶部显示所选项目的方法 .

在一个 ListView 中,我能够通过使用 scrollTo(x,y) 并获得需要居中的元素的顶部来做到这一点 .

就像是:

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

问题是 RecyclerView 在使用它的 scrollTo 方法时会返回错误

RecyclerView不支持滚动到绝对位置

如何滚动 RecyclerView 将所选项目放在视图顶部?

12 回答

  • 5

    与速度调节器相同

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

    你只需要拨打 recyclerview.scrollToPosition(position) . 没关系!

    如果要在适配器中调用它,只需让适配器具有recyclelerview实例或包含recyclerview的活动或片段,而不是在其中实现方法 getRecyclerview() .

    我希望它可以帮到你 .

  • 11

    在特定位置滚动
    这对我很有帮助 . 通过单击侦听器,您可以获得适配器中的位置

    layoutmanager.scrollToPosition(int position);
    
  • 0
    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);**
    
  • -3

    如果您使用的是LinearLayoutManager或StaggeredGridLayoutManager,它们每个都有一个scrollToPositionWithOffset方法,它从RecyclerView的开头获取项目开头的位置和偏移量,这似乎可以完成您的需要(设置偏移量) 0应该与顶部对齐) .

    例如:

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

    在我的情况下,我的 RecyclerView 有这样的填充顶部

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

    然后,为了将项目滚动到顶部,我需要

    recyclerViewLinearLayoutManager.scrollToPositionWithOffset(position, -yourRecyclerView.getPaddingTop());
    
  • 6

    尝试一下对我有用的东西!

    创建一个变量 private static int displayedposition = 0;

    现在,您可以在Activity中找到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 /

  • 309

    在点击按钮后刷新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 .

  • 39

    如果您正在寻找垂直LinearLayout Manager,您可以使用自定义 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); 将平滑滚动到选定位置到回收器视图的顶部

  • 3

    //滚动项目pos

    linearLayoutManager.scrollToPositionWithOffset(pos, 0);
    
  • 0

    只需简单地调用此方法:

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

    代替:

    RecyclerView.scrollToPosition(yourItemPosition);
    
  • 1

    我使用下面的代码将项目(thisView)平滑滚动到顶部 .
    它也适用于GridLayoutManager,具有不同高度的视图:

    View firstView = mRecyclerView.getChildAt(0);
    int toY = firstView.getTop();
    int firstPosition = mRecyclerView.getChildAdapterPosition(firstView);
    View thisView = mRecyclerView.getChildAt(thisPosition - firstPosition);
    int fromY = thisView.getTop();
    
    mRecyclerView.smoothScrollBy(0, fromY - toY);
    

    似乎工作得很好,可以快速解决问题 .

相关问题