RecyclerView android 纵向自动滚动实现
时间: 2023-11-16 15:14:10 浏览: 120
RecyclerView实现纵向和横向滚动
RecyclerView 的纵向自动滚动实现可以使用 RecyclerView 自带的 LayoutManager 或者自定义 LayoutManager 实现。
使用 RecyclerView 自带的 LayoutManager 实现纵向自动滚动:
1. 获取 RecyclerView 的 LinearLayoutManager 对象
2. 创建一个 Handler 对象和一个 Runnable 对象
3. 在 Runnable 的 run() 方法中,调用 LinearLayoutManager 的 smoothScrollToPosition() 方法实现自动滚动
4. 在 Handler 中使用 postDelayed() 方法,指定延迟时间和 Runnable 对象,实现定时滚动。
示例代码如下:
```
private LinearLayoutManager mLinearLayoutManager;
private Handler mHandler = new Handler();
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
int currentPos = mLinearLayoutManager.findFirstVisibleItemPosition();
mLinearLayoutManager.smoothScrollToPosition(mRecyclerView, null, currentPos + 1);
mHandler.postDelayed(this, 3000); // 延迟 3 秒滚动
}
};
private void initRecyclerView() {
mLinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
private void startAutoScroll() {
mHandler.postDelayed(mRunnable, 3000); // 延迟 3 秒滚动
}
private void stopAutoScroll() {
mHandler.removeCallbacks(mRunnable);
}
```
使用自定义 LayoutManager 实现纵向自动滚动:
1. 自定义一个继承自 LinearLayoutManager 的 LayoutManager
2. 在 LayoutManager 的 onLayoutChildren() 方法中,调用 super.onLayoutChildren() 方法完成布局,并获取第一个和最后一个可见 item 的位置
3. 在 LayoutManager 的 scrollVerticallyBy() 方法中,判断当前滑动的距离是否大于等于一个屏幕的高度,如果是,则调用 scrollToPosition() 方法实现自动滚动。
示例代码如下:
```
public class AutoScrollLayoutManager extends LinearLayoutManager {
private int mScreenHeight;
public AutoScrollLayoutManager(Context context) {
super(context);
mScreenHeight = context.getResources().getDisplayMetrics().heightPixels;
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
int firstVisiblePos = findFirstVisibleItemPosition();
int lastVisiblePos = findLastVisibleItemPosition();
if (lastVisiblePos - firstVisiblePos < state.getItemCount() - 1) { // 如果可见 item 数量小于总 item 数量,强制重新布局
detachAndScrapAttachedViews(recycler);
layoutChildren(recycler, state);
}
}
private void layoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
int offsetY = 0;
for (int i = 0; i < getItemCount(); i++) {
View view = recycler.getViewForPosition(i);
addView(view);
measureChildWithMargins(view, 0, 0);
int width = getDecoratedMeasuredWidth(view);
int height = getDecoratedMeasuredHeight(view);
layoutDecorated(view, 0, offsetY, width, offsetY + height);
offsetY += height;
}
}
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
int travel = dy;
if (dy > 0) { // 手指向上滑动
View lastVisibleView = getChildAt(getChildCount() - 1);
int lastVisiblePos = getPosition(lastVisibleView);
if (lastVisibleView.getBottom() - dy < mScreenHeight) { // 如果最后一个可见 item 没有完全显示,就不滑动
travel = 0;
} else if (lastVisiblePos == getItemCount() - 1) { // 如果滑到最后一个 item,就不滑动
travel = 0;
}
}
int realScroll = super.scrollVerticallyBy(travel, recycler, state);
if (realScroll != travel) { // 如果滑动距离小于手指滑动距离,说明已经滑到边界了,就自动滚动
int currentPos = findFirstVisibleItemPosition();
scrollToPosition(currentPos + 1);
}
return realScroll;
}
}
```
使用自定义的 AutoScrollLayoutManager:
```
private AutoScrollLayoutManager mLayoutManager;
private void initRecyclerView() {
mLayoutManager = new AutoScrollLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
private void startAutoScroll() {
mRecyclerView.smoothScrollToPosition(mAdapter.getItemCount() - 1); // 先滚动到最后一个 item
mHandler.postDelayed(mRunnable, 3000); // 延迟 3 秒开始自动滚动
}
private void stopAutoScroll() {
mHandler.removeCallbacks(mRunnable);
}
```
阅读全文