lon*_*ngi 51 android scroll position android-recyclerview
我正在使用一个Scrollview
无限的"Time Picker Carousel"并发现它不是最好的方法(最后一个问题)
现在,我找到了Recycler View,但是我无法在recyclerView的X方向上获得当前的滚动偏移量?(假设每个项目的宽度为100px,第二个项目只有50%可见,因此滚动偏移量为150px)
recyclerView.getScrollX()
返回0
(文档说:初始滚动值)LayoutManager
有findFirstVisibleItemPosition
,但我不能算出X与偏移UPDATE
我刚刚找到了一种方法来跟踪X-Position,同时使用onScrolled
回调更新值,但我更喜欢获取实际值而不是一直跟踪它!
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);
}
});
Run Code Online (Sandbox Code Playgroud)
Uma*_*shi 56
RecyclerView已经有获得水平和垂直滚动偏移的方法
mRecyclerView.computeHorizontalScrollOffset()
mRecyclerView.computeVerticalScrollOffset()
Run Code Online (Sandbox Code Playgroud)
这适用于包含相同高度(垂直滚动偏移)和相同宽度(水平滚动偏移)的单元格的RecyclerViews
lon*_*ngi 50
解决方案1: setOnScrollListener
将您的X-Position保存为类变量并更新其中的每个更改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);
}
});
Run Code Online (Sandbox Code Playgroud)
解决方案2:计算当前位置.
在我的情况下,我有一个水平列表,其中填充了时间值(0:00,0:30,1:00,1:30 ...... 23:00,23:30).我正在计算时间项目的时间,该时间项目位于屏幕中间(计算点).这就是为什么我需要我的确切X-Scroll位置RecycleView
第一项(标题项)有一个额外的填充,将0分钟设置为中心
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);
}
});
Run Code Online (Sandbox Code Playgroud)
}
jbo*_*ren 33
感谢@ umar-qureshi的正确领导!看来,你可以确定与滚动百分比Offset
,Extent
和Range
这样
percentage = 100 * offset / (range - extent)
Run Code Online (Sandbox Code Playgroud)
例如(要放入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 + "%");
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
比你需要获得抵消的地方:
recyclerView.getHorizontalOffset()
Run Code Online (Sandbox Code Playgroud)
如果您需要知道当前页面及其相对于 RecyclerView 宽度的偏移量,您可能想尝试这样的事情:
recyclerView.addOnScrollListener(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);
final int scrollOffset = recyclerView.computeHorizontalScrollOffset();
final int width = recyclerView.getWidth();
final int currentPage = scrollOffset / width;
final float pageOffset = (float) (scrollOffset % width) / width;
// the following lines just the example of how you can use it
if (currentPage == 0) {
leftIndicator.setAlpha(pageOffset);
}
if (adapter.getItemCount() <= 1) {
rightIndicator.setAlpha(pageOffset);
} else if (currentPage == adapter.getItemCount() - 2) {
rightIndicator.setAlpha(1f - pageOffset);
}
}
});
Run Code Online (Sandbox Code Playgroud)
如果currentPage
索引为 0,则leftIndicator
(箭头)将是透明的,rightIndicator
如果只有一个page
(在示例中,适配器始终至少显示一项,因此不会检查空值)。
这样一来,如果你一直在使用回调,你会基本上有几乎相同的功能pageScrolled
的ViewPager.OnPageChangeListener
。
归档时间: |
|
查看次数: |
74342 次 |
最近记录: |