方法
- scrollToPosition
不在屏幕Item移至屏幕,原上方Item移至可见头项,原下方移至屏幕可见末项。已显Item不移。 - scrollToPositionWithOffset
Item移至可见头项(即使已于可见Item中)。参数offset表Item移至头项后同RecyclerView上或下边间距(默0)。 - scrollBy
据偏移量移。 - scrollTo
移至坐标点。
场景一
滑至某位。
实现一
布局管理器
((LinearLayoutManager) rvParaConfigComplexType.getLayoutManager()).scrollToPositionWithOffset(position, 0);
((LinearLayoutManager) rvParaConfigComplexType.getLayoutManager()).setStackFromEnd(true);
complexTypeList.add(position, complexType);
paraConfigChooseComplexTypeAdapter.notifyItemInserted(position);
paraConfigChooseComplexTypeAdapter.notifyItemRangeChanged(position, complexTypeList.size() - position);
实现二
据当前RecyclerView条数(有效避指针越界)
package util;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
/**
* Created on 2018/6/28.
*
* @desc RecyclerViewScrollController
*/
public class RecyclerViewScrollController {
/**
* 滑至某位
*
* @param manager 布局管理器
* @param mRecyclerView recyclerView
* @param n 位
*/
public static void ScrollToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int n) {
int firstItem = manager.findFirstVisibleItemPosition();
int lastItem = manager.findLastVisibleItemPosition();
if (n <= firstItem) {
mRecyclerView.scrollToPosition(n);
} else if (n <= lastItem) {
int top = mRecyclerView.getChildAt(n - firstItem).getTop();
mRecyclerView.scrollBy(0, top);
} else {
mRecyclerView.scrollToPosition(n);
}
}
}
RecyclerViewScrollController.ScrollToPosition(((LinearLayoutManager) rvParaConfigComplexType.getLayoutManager()), rvParaConfigComplexType, 0);
实现三
平滑一
package widget.recyclerview;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created on 2018/6/28.
*
* @author 郑少鹏
* @desc RecyclerViewScrollController
*/
public class RecyclerViewScrollController {
/**
* 应滑否(目标项于最后一可见项后否)
*/
private boolean shouldScroll;
/**
* 目标位
*/
private int targetPosition;
/**
* 平滑至目标位
*
* @param recyclerView 控件
* @param position 位
*/
private void smoothScrollToTargetPosition(RecyclerView recyclerView, final int position) {
// 头可见项
int firstItem = recyclerView.getChildLayoutPosition(recyclerView.getChildAt(0));
// 末可见项
int lastItem = recyclerView.getChildLayoutPosition(recyclerView.getChildAt(recyclerView.getChildCount() - 1));
if (position < firstItem) {
// 跳转位于头可见项前时smoothScrollToPosition可直跳
recyclerView.smoothScrollToPosition(position);
} else if (position <= lastItem) {
// 跳转位于头可见项后末可见项前时,smoothScrollToPosition根本不动,此时调smoothScrollBy滑至指定位
int movePosition = position - firstItem;
if (movePosition >= 0 && movePosition < recyclerView.getChildCount()) {
int top = recyclerView.getChildAt(movePosition).getTop();
recyclerView.smoothScrollBy(0, top);
}
} else {
// 跳转位于末可见项后时先调smoothScrollToPosition将跳转位滑至可见位
// 再通onScrollStateChanged控制再调smoothMoveToPosition执行上判断中法
recyclerView.smoothScrollToPosition(position);
targetPosition = position;
shouldScroll = true;
}
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (shouldScroll) {
shouldScroll = false;
flatSlidingToTargetPosition(recyclerView, targetPosition);
}
}
});
}
}
RecyclerViewScrollController recyclerViewScrollController = new RecyclerViewScrollController();
recyclerViewScrollController.smoothScrollToTargetPosition(pharmaceuticalKnowledgeTwoLevelClassificationFragmentRv, position);
平滑二
package widget.recyclerview;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created on 2018/6/28.
*
* @author 郑少鹏
* @desc RecyclerViewScrollController
*/
public class RecyclerViewScrollController {
private boolean move;
private int index;
/**
* 平滑至目标位
*
* @param recyclerView 控件
* @param position 位
*/
public void smoothScrollToTargetPosition(RecyclerView recyclerView, int position) {
LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (manager != null) {
// 滑至指定位
// 记录(第三种情况用到)
this.index = position;
// 当前屏幕可见头项与末项
int firstItem = manager.findFirstVisibleItemPosition();
int lastItem = manager.findLastVisibleItemPosition();
// 区分
if (position <= firstItem) {
// 所置顶项于当前显示头项前
recyclerView.smoothScrollToPosition(position);
} else if (position <= lastItem) {
// 所置顶项已于屏幕上
int top = recyclerView.getChildAt(position - firstItem).getTop();
recyclerView.smoothScrollBy(0, top);
} else {
// 所置顶项于当前显示末项后
recyclerView.smoothScrollToPosition(position);
move = true;
}
// 滑动监听
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
// 此处第二次滚动
if (move) {
move = false;
// 所置顶项于当前屏幕位,mIndex记录所置顶于RecyclerView中位
int n = index - manager.findFirstVisibleItemPosition();
if (0 <= n && n < recyclerView.getChildCount()) {
// 所置顶项顶距RecyclerView顶距离
int top = recyclerView.getChildAt(n).getTop();
// 最后移动
recyclerView.smoothScrollBy(0, top);
}
}
}
});
}
}
}
RecyclerViewScrollController recyclerViewScrollController = new RecyclerViewScrollController();
recyclerViewScrollController.smoothScrollToTargetPosition(pharmaceuticalKnowledgeTwoLevelClassificationFragmentRv, position);
平滑三
/**
* 通滑动模式平滑至目标位
*
* @param recyclerView 控件
* @param targetPosition 目标位
* @param scrollMode 滑动模式(默SNAP_TO_ANY)
* {@link LinearSmoothScroller#SNAP_TO_START}
* 子视图左侧或顶部对齐父视图左侧或顶部。
* {@link LinearSmoothScroller#SNAP_TO_END}
* 子视图右侧或底部对齐父视图右侧面或底部。
* {@link LinearSmoothScroller#SNAP_TO_ANY}
* 据子视图当前位与父布局关系定子视图从头到尾跟随否。
* 子视图实际于RecyclerView左侧,SNAP_TO_ANY和SNAP_TO_START无差别。
*/
public void smoothScrollToTargetPositionWithScrollMode(RecyclerView recyclerView, int targetPosition, int scrollMode) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (null == linearLayoutManager) {
return;
}
LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
@Override
protected int getVerticalSnapPreference() {
return scrollMode;
}
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return linearLayoutManager.computeScrollVectorForPosition(targetPosition);
}
};
recyclerView.setLayoutManager(linearLayoutManager);
// 滑
linearSmoothScroller.setTargetPosition(targetPosition);
linearLayoutManager.startSmoothScroll(linearSmoothScroller);
}
RecyclerViewScrollController recyclerViewScrollController = new RecyclerViewScrollController();
recyclerViewScrollController.smoothScrollToTargetPositionWithScrollMode(contactActivityRv, contactBeanList.size() - 1, LinearSmoothScroller.SNAP_TO_START);
场景二
条目滑至居中
实现
/**
* 条目滑至居中
*
* @param recyclerView 控件
* @param position 位
*/
public void itemScrollToCenter(RecyclerView recyclerView, int position) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (linearLayoutManager != null) {
int firstPosition = linearLayoutManager.findFirstVisibleItemPosition();
int lastPosition = linearLayoutManager.findLastVisibleItemPosition();
int left = recyclerView.getChildAt(position - firstPosition).getLeft();
int right = recyclerView.getChildAt(lastPosition - position).getLeft();
recyclerView.scrollBy((left - right) / 2, 0);
}
}
工具类
package com.zsp.library.recyclerview;
import android.graphics.PointF;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created on 2018/6/28.
*
* @author 郑少鹏
* @desc RecyclerViewScrollController
*/
public class RecyclerViewScrollController {
private boolean move;
private int index;
/**
* 平滑至目标位
*
* @param recyclerView 控件
* @param position 位
*/
public void smoothScrollToTargetPosition(RecyclerView recyclerView, int position) {
LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (manager != null) {
// 滑至指定位
// 记录(第三种情况用到)
this.index = position;
// 当前屏幕可见头项与末项
int firstItem = manager.findFirstVisibleItemPosition();
int lastItem = manager.findLastVisibleItemPosition();
// 区分
if (position <= firstItem) {
// 所置顶项于当前显示头项前
recyclerView.smoothScrollToPosition(position);
} else if (position <= lastItem) {
// 所置顶项已于屏幕上
int top = recyclerView.getChildAt(position - firstItem).getTop();
recyclerView.smoothScrollBy(0, top);
} else {
// 所置顶项于当前显示末项后
recyclerView.smoothScrollToPosition(position);
move = true;
}
// 滑动监听
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
// 此处第二次滚动
if (move) {
move = false;
// 所置顶项于当前屏幕位,mIndex记录所置顶于RecyclerView中位
int n = index - manager.findFirstVisibleItemPosition();
if (0 <= n && n < recyclerView.getChildCount()) {
// 所置顶项顶距RecyclerView顶距离
int top = recyclerView.getChildAt(n).getTop();
// 最后移动
recyclerView.smoothScrollBy(0, top);
}
}
}
});
}
}
/**
* 通滑动模式平滑至目标位
*
* @param recyclerView 控件
* @param targetPosition 目标位
* @param scrollMode 滑动模式(默SNAP_TO_ANY)
* {@link LinearSmoothScroller#SNAP_TO_START}
* 子视图左侧或顶部对齐父视图左侧或顶部。
* {@link LinearSmoothScroller#SNAP_TO_END}
* 子视图右侧或底部对齐父视图右侧面或底部。
* {@link LinearSmoothScroller#SNAP_TO_ANY}
* 据子视图当前位与父布局关系定子视图从头到尾跟随否。
* 子视图实际于RecyclerView左侧,SNAP_TO_ANY和SNAP_TO_START无差别。
*/
public void smoothScrollToTargetPositionWithScrollMode(RecyclerView recyclerView, int targetPosition, int scrollMode) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (null == linearLayoutManager) {
return;
}
LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
@Override
protected int getVerticalSnapPreference() {
return scrollMode;
}
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return linearLayoutManager.computeScrollVectorForPosition(targetPosition);
}
};
recyclerView.setLayoutManager(linearLayoutManager);
// 滑
linearSmoothScroller.setTargetPosition(targetPosition);
linearLayoutManager.startSmoothScroll(linearSmoothScroller);
}
/**
* 条目滑至居中
*
* @param recyclerView 控件
* @param position 位
*/
public void itemScrollToCenter(RecyclerView recyclerView, int position) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (linearLayoutManager != null) {
int firstPosition = linearLayoutManager.findFirstVisibleItemPosition();
int lastPosition = linearLayoutManager.findLastVisibleItemPosition();
int left = recyclerView.getChildAt(position - firstPosition).getLeft();
int right = recyclerView.getChildAt(lastPosition - position).getLeft();
recyclerView.scrollBy((left - right) / 2, 0);
}
}
}
本文介绍RecyclerView滑动控制方法,包括直接定位、偏移量滑动、平滑滑动及居中显示等技巧,并提供多种实现方式,适用于不同场景。
2488

被折叠的 条评论
为什么被折叠?



