Android:如何获取 RecyclerView 的当前 X 偏移量? [英] Android: How to get the current X offset of RecyclerView?

查看:65
本文介绍了Android:如何获取 RecyclerView 的当前 X 偏移量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将 Scrollview 用于无限的时间选择器轮播"并发现这不是最好的方法 (最后一个问题)

I'm using a Scrollview for an infinite "Time Picker Carousel" and found out, that it is not the best approach (last question)

现在,我找到了 Recycler View 但是我无法获取recyclerView X 方向的当前滚动偏移?(假设每个项目的宽度为 100 像素,第二个项目仅对 50% 可见,因此滚动偏移为 150 像素)

Now, I found the Recycler View but I am unable to get the current scroll offset in X direction of the recyclerView? (Let's say each item is 100px width, and the second item is only visible to 50%, so the scroll-offset is 150px)

  • 所有项目都具有相同的宽度,但在第一个项目之前和最后一个项目之后有一些间隙
  • recyclerView.getScrollX() 返回 0(文档说:初始滚动值)
  • LayoutManagerfindFirstVisibleItemPosition,但我无法用它计算 X 偏移量
  • all items have the same width, but therer is some gap before the first, after the last item
  • recyclerView.getScrollX() returns 0 (docs say: initial scroll value)
  • the LayoutManager has findFirstVisibleItemPosition, but I cannot calculate the X offset with that

更新

我刚刚找到了一种方法来保持跟踪 X 位置,同时使用 onScrolled 回调更新值,但我更喜欢获取实际值而不是一直跟踪它!

I just found a way to keep tracking the X-Position, while updating the value with the onScrolled callback, but I would prefer getting the actual value instead of tracking it all the time!

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

        }
    });

推荐答案

方案一: setOnScrollListener

将您的 X-Position 保存为类变量并更新 onScrollListener 中的每个更改.确保您没有重置 overallXScroll(例如 onScreenRotationChange)

Save your X-Position as class variable and update each change within the onScrollListener. Ensure you don't reset overallXScroll (f.e. 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);

    }
 });

解决方案 2: 计算当前位置.

就我而言,我有一个水平列表,其中填充了时间值(0:00、0:30、1:00、1:30 ... 23:00、23:30).我正在计算时间项,它位于屏幕中间(计算点).这就是为什么我需要 RecycleView

In my case, I have a horizontal List which is filled with time values (0:00, 0:30, 1:00, 1:30 ... 23:00, 23:30). I'm calculating the time from the time-item, which is in the middle of the screen (calculation point). That's why I need the exact X-Scroll Position of my RecycleView

  • 每个时间项具有相同的 60dp 宽度(仅供参考:60dp = 30min,2dp = 1min)
  • 第一项(标题项)有一个额外的填充,将 0min 设置为中心

  • Each time item has the same width of 60dp (fyi: 60dp = 30min, 2dp = 1min)
  • First item (Header item) has an extra padding, to set 0min to the center

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

    }
});

}

这篇关于Android:如何获取 RecyclerView 的当前 X 偏移量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆