Android: How to get the current X offset of RecyclerView? Android: How to get the current X offset of RecyclerView? android android

Android: How to get the current X offset of RecyclerView?


RecyclerView already have method to get horizontal and vertical scroll offset

mRecyclerView.computeHorizontalScrollOffset()mRecyclerView.computeVerticalScrollOffset()

This will work for RecyclerViews containing cells of the same height (for vertical scroll offset) and the same width (for horizontal scroll offset)


enter image description here

Solution 1: setOnScrollListener

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

Solution 2: Calculate current position.

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

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

    }


Thanks to @umar-qureshi for the right lead! It appears that you can determine the scroll percentage with Offset, Extent, and Range such that

percentage = 100 * offset / (range - extent)

For example (to be put in an 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 + "%");