Android:如何获取 RecyclerView 的当前 X 偏移量? [英] Android: How to get the current X offset of RecyclerView?
问题描述
我将 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
(文档说:初始滚动值)LayoutManager
有findFirstVisibleItemPosition
,但我无法用它计算 X 偏移量
- all items have the same width, but therer is some gap before the first, after the last item
recyclerView.getScrollX()
returns0
(docs say: initial scroll value)- the
LayoutManager
hasfindFirstVisibleItemPosition
, 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屋!