当前位置:网站首页>Recyclerview paging slide
Recyclerview paging slide
2022-07-05 11:57:00 【asahi_ xin】
frame
First step : preparation
api 'com.android.support:recyclerview-v7:26.1.0'
PagingScrollHelper
public class PagingScrollHelper {
private RecyclerView mRecyclerView = null;
private MyOnScrollListener mOnScrollListener = new MyOnScrollListener();
private MyOnFlingListener mOnFlingListener = new MyOnFlingListener();
private int offsetY = 0;
private int offsetX = 0;
private int startY = 0;
private int startX = 0;
enum ORIENTATION {
HORIZONTAL, VERTICAL, NULL
}
private ORIENTATION mOrientation = ORIENTATION.HORIZONTAL;
public void setUpRecycleView(RecyclerView recycleView) {
if (recycleView == null) {
throw new IllegalArgumentException("recycleView must be not null");
}
mRecyclerView = recycleView;
// Handle sliding
recycleView.setOnFlingListener(mOnFlingListener);
// Set scrolling monitor , Record the status of scrolling , And the total offset
recycleView.setOnScrollListener(mOnScrollListener);
// Record the position where the scroll starts
recycleView.setOnTouchListener(mOnTouchListener);
// Get the direction of scrolling
updateLayoutManger();
}
public void updateLayoutManger() {
RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager();
if (layoutManager != null) {
if (layoutManager.canScrollVertically()) {
mOrientation = ORIENTATION.VERTICAL;
} else if (layoutManager.canScrollHorizontally()) {
mOrientation = ORIENTATION.HORIZONTAL;
} else {
mOrientation = ORIENTATION.NULL;
}
if (mAnimator != null) {
mAnimator.cancel();
}
startX = 0;
startY = 0;
offsetX = 0;
offsetY = 0;
}
}
/** * Get total pages */
public int getPageCount() {
if (mRecyclerView != null) {
if (mOrientation == ORIENTATION.NULL) {
return 0;
}
if (mOrientation == ORIENTATION.VERTICAL && mRecyclerView.computeVerticalScrollExtent() != 0) {
return mRecyclerView.computeVerticalScrollRange() / mRecyclerView.computeVerticalScrollExtent();
} else if (mRecyclerView.computeHorizontalScrollExtent() != 0) {
return mRecyclerView.computeHorizontalScrollRange() / mRecyclerView.computeHorizontalScrollExtent();
}
}
return 0;
}
private ValueAnimator mAnimator = null;
public void scrollToPosition(int position) {
if (mAnimator == null) {
mOnFlingListener.onFling(0, 0);
}
if (mAnimator != null) {
int startPoint = mOrientation == ORIENTATION.VERTICAL ? offsetY : offsetX, endPoint = 0;
if (mOrientation == ORIENTATION.VERTICAL) {
endPoint = mRecyclerView.getHeight() * position;
} else {
endPoint = mRecyclerView.getWidth() * position;
}
if (startPoint != endPoint) {
mAnimator.setIntValues(startPoint, endPoint);
mAnimator.start();
}
}
}
public class MyOnFlingListener extends RecyclerView.OnFlingListener {
@Override
public boolean onFling(int velocityX, int velocityY) {
if (mOrientation == ORIENTATION.NULL) {
return false;
}
// Get the page where scrolling is started index
int p = getStartPageIndex();
// The beginning and end of the scroll
int endPoint = 0;
int startPoint = 0;
// If it's vertical
if (mOrientation == ORIENTATION.VERTICAL) {
startPoint = offsetY;
if (velocityY < 0) {
p--;
} else if (velocityY > 0) {
p++;
}
// More different speeds to judge the direction of rolling
// Be careful , Here's a trick , When the speed is 0 Scroll the page that will start when , That is to realize page reset
endPoint = p * mRecyclerView.getHeight();
} else {
startPoint = offsetX;
if (velocityX < 0) {
p--;
} else if (velocityX > 0) {
p++;
}
endPoint = p * mRecyclerView.getWidth();
}
if (endPoint < 0) {
endPoint = 0;
}
// Use animation to handle scrolling
if (mAnimator == null) {
mAnimator = new ValueAnimator().ofInt(startPoint, endPoint);
mAnimator.setDuration(300);
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int nowPoint = (int) animation.getAnimatedValue();
if (mOrientation == ORIENTATION.VERTICAL) {
int dy = nowPoint - offsetY;
// Through here RecyclerView Of scrollBy Method to realize scrolling .
mRecyclerView.scrollBy(0, dy);
} else {
int dx = nowPoint - offsetX;
mRecyclerView.scrollBy(dx, 0);
}
}
});
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// Callback monitor
if (null != mOnPageChangeListener) {
mOnPageChangeListener.onPageChange(getPageIndex());
}
// Repair double click item bug
mRecyclerView.stopScroll();
startY = offsetY;
startX = offsetX;
}
});
} else {
mAnimator.cancel();
mAnimator.setIntValues(startPoint, endPoint);
}
mAnimator.start();
return true;
}
}
public class MyOnScrollListener extends RecyclerView.OnScrollListener {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
//newState==0 Indicates that scrolling stops , At this point, you need to deal with rollback
if (newState == 0 && mOrientation != ORIENTATION.NULL) {
boolean move;
int vX = 0, vY = 0;
if (mOrientation == ORIENTATION.VERTICAL) {
int absY = Math.abs(offsetY - startY);
// If you slide more than half of the screen, you need to slide to the next page
move = absY > recyclerView.getHeight() / 2;
vY = 0;
if (move) {
vY = offsetY - startY < 0 ? -1000 : 1000;
}
} else {
int absX = Math.abs(offsetX - startX);
move = absX > recyclerView.getWidth() / 2;
if (move) {
vX = offsetX - startX < 0 ? -1000 : 1000;
}
}
mOnFlingListener.onFling(vX, vY);
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
// At the end of scrolling, record the offset of scrolling
offsetY += dy;
offsetX += dx;
}
}
private MyOnTouchListener mOnTouchListener = new MyOnTouchListener();
private boolean firstTouch = true;
public class MyOnTouchListener implements View.OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
// Record the coordinates when the finger is pressed
if (firstTouch) {
// for the first time touch May be ACTION_MOVE or ACTION_DOWN, So use this way to judge
firstTouch = false;
startY = offsetY;
startX = offsetX;
}
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
firstTouch = true;
}
return false;
}
}
private int getPageIndex() {
int p = 0;
if (mRecyclerView.getHeight() == 0 || mRecyclerView.getWidth() == 0) {
return p;
}
if (mOrientation == ORIENTATION.VERTICAL) {
p = offsetY / mRecyclerView.getHeight();
} else {
p = offsetX / mRecyclerView.getWidth();
}
return p;
}
private int getStartPageIndex() {
int p = 0;
if (mRecyclerView.getHeight() == 0 || mRecyclerView.getWidth() == 0) {
// Can't handle without width and height
return p;
}
if (mOrientation == ORIENTATION.VERTICAL) {
p = startY / mRecyclerView.getHeight();
} else {
p = startX / mRecyclerView.getWidth();
}
return p;
}
private onPageChangeListener mOnPageChangeListener;
public void setOnPageChangeListener(onPageChangeListener listener) {
mOnPageChangeListener = listener;
}
public interface onPageChangeListener {
void onPageChange(int index);
}
}
VerticalDecoration
public class VerticalDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
};
private static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
private static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mDivider;
private int mOrientation;
public VerticalDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
}
@Override
public void onDraw(Canvas c, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
private void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
Second parts : call
// Initialize the paging tool class
PagingScrollHelper pagingScrollHelper = new PagingScrollHelper();
mRecyclerView.setAdapter(mainAdapter);
pagingScrollHelper.setUpRecycleView(mRecyclerView);
mRecyclerView.setHorizontalScrollBarEnabled(true);
VerticalDecoration verticalDecoration = new VerticalDecoration(this, LinearLayoutManager.HORIZONTAL);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.addItemDecoration(verticalDecoration);
pagingScrollHelper.updateLayoutManger();
pagingScrollHelper.scrollToPosition(0);
边栏推荐
猜你喜欢
Pytorch MLP
[yolov3 loss function]
Redis cluster (master-slave) brain crack and solution
Is it difficult to apply for a job after graduation? "Hundreds of days and tens of millions" online recruitment activities to solve your problems
【 YOLOv3中Loss部分计算】
Hiengine: comparable to the local cloud native memory database engine
【L1、L2、smooth L1三类损失函数】
【上采样方式-OpenCV插值】
liunx禁ping 详解traceroute的不同用法
Troubleshooting of high memory usage of redis in a production environment
随机推荐
【pytorch 修改预训练模型:实测加载预训练模型与模型随机初始化差别不大】
Hash tag usage in redis cluster
【load dataset】
COMSOL -- establishment of 3D graphics
Multi table operation - sub query
13.(地图数据篇)百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
SET XACT_ ABORT ON
[upsampling method opencv interpolation]
一次生产环境redis内存占用居高不下问题排查
yolov5目标检测神经网络——损失函数计算原理
JS for循环 循环次数异常
abap查表程序
Vscode shortcut key
2048 game logic
1 plug-in to handle advertisements in web pages
Is investment and finance suitable for girls? What financial products can girls buy?
报错ModuleNotFoundError: No module named ‘cv2.aruco‘
Wireless WiFi learning 8-channel transmitting remote control module
阻止瀏覽器後退操作
网络五连鞭