Android:如何获得RecyclerView的当前X偏移量?

我正在使用一个Scrollview查看一个无限的“时间select器旋转木马”,并发现,这不是最好的办法( 最后一个问题 )

现在,我find了Recycler View,但是我无法获得recyclerView的X方向上的当前滚动偏移量 ? (假设每个项目的宽度是100px,第二个项目只能看到50%,所以scroll-offset是150px)

  • 所有项目都有相同的宽度,但是在最后一个项目之后的第一个项目之前有一些差距
  • recyclerView.getScrollX()返回0 (文档说:初始滚动值)
  • LayoutManagerfindFirstVisibleItemPosition ,但是我不能用这个来计算X偏移量

UPDATE

我只是find了一种方法来跟踪X位置,同时使用onScrolledcallback来更新值,但我更喜欢获取实际值而不是始终跟踪它!

 private int overallXScroll = 0; //... mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); overallXScroll = overallXScroll + dx; Log.i("check","overallXScroll->" + overallXScroll); } }); 

RecyclerView已经有了获取水平和垂直滚动偏移量的方法

 mRecyclerView.computeHorizontalScrollOffset() mRecyclerView.computeVerticalScrollOffset() 

这将适用于包含相同高度(对于垂直滚动偏移)和相同宽度(对于水平滚动偏移)的单元的RecyclerViews,

在这里输入图像说明

解决scheme1: setOnScrollListener

将您的X-Position保存为类variables,并更新onScrollListener每个更改。 确保您不会重置overallXScroll (fe onScreenRotationChange

  private int overallXScroll = 0; //... mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); overallXScroll = overallXScroll + dx; Log.i("check","overall X = " + overallXScroll); } }); 

解决scheme2:计算当前位置。

在我的情况下,我有一个充满时间值的水平列表(0:00,0:30,1:00,1:30 … 23:00,23:30)。 我正在计算屏幕中间的时间项目(计算点)的时间。 这就是为什么我需要我的RecycleView的确切X-Scroll位置

  • 每个项目具有相同的宽度60dp(fyi:60dp = 30min,2dp = 1min)
  • 第一个项目(Header项目)有一个额外的填充,设置0min到中心

     private int mScreenWidth = 0; private int mHeaderItemWidth = 0; private int mCellWidth = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //init recycle views //... LinearLayoutManager mLLM = (LinearLayoutManager) getLayoutManager(); DisplayMetrics displaymetrics = new DisplayMetrics(); this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); this.mScreenWidth = displaymetrics.widthPixels; //calculate value on current device mCellWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources() .getDisplayMetrics()); //get offset of list to the right (gap to the left of the screen from the left side of first item) final int mOffset = (this.mScreenWidth / 2) - (mCellWidth / 2); //HeaderItem width (blue rectangle in graphic) mHeaderItemWidth = mOffset + mCellWidth; mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); //get first visible item View firstVisibleItem = mLLM.findViewByPosition(mLLM.findFirstVisibleItemPosition()); int leftScrollXCalculated = 0; if (firstItemPosition == 0){ //if first item, get width of headerview (getLeft() < 0, that's why I Use Math.abs()) leftScrollXCalculated = Math.abs(firstVisibleItem.getLeft()); } else{ //X-Position = Gap to the right + Number of cells * width - cell offset of current first visible item //(mHeaderItemWidth includes already width of one cell, that's why I have to subtract it again) leftScrollXCalculated = (mHeaderItemWidth - mCellWidth) + firstItemPosition * mCellWidth + firstVisibleItem.getLeft(); } Log.i("asdf","calculated X to left = " + leftScrollXCalculated); } }); 

    }

感谢@ umar-qureshi的正确领导! 看起来,您可以使用OffsetExtentRange来确定滚动百分比

 percentage = 100 * offset / (range - extent) 

例如(要放在OnScrollListener ):

 int offset = recyclerView.computeVerticalScrollOffset(); int extent = recyclerView.computeVerticalScrollExtent(); int range = recyclerView.computeVerticalScrollRange(); int percentage = (int)(100.0 * offset / (float)(range - extent)); Log.i("RecyclerView, "scroll percentage: "+ percentage + "%"); 
 public class CustomRecyclerView extends RecyclerView { public CustomRecyclerView(Context context) { super(context); } public CustomRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public int getHorizontalOffset() { return super.computeHorizontalScrollOffset(); } } 

比你需要得到抵消的地方:

 recyclerView.getHorizontalOffset()