//当前滑动距离
private int offsetY = 0;
private int offsetX = 0;
//按下屏幕点
private int startY = 0;
private int startX = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
//手指按下的时候记录开始滚动的坐标
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//手指按下的开始坐标
startY = offsetY;
startX = offsetX;
}
return false;
}
}
@Override
public void scrollTo(int x, int y) {
Log.w(TAG, "RecyclerView does not support scrolling to an absolute position. "
+ "Use scrollToPosition instead");
}
/**
* This class defines the behavior of fling if the developer wishes to handle it.
* <p>
* Subclasses of {@link OnFlingListener} can be used to implement custom fling behavior.
*
* @see #setOnFlingListener(OnFlingListener)
*/
public static abstract class OnFlingListener {
/**
* Override this to handle a fling given the velocities in both x and y directions.
* Note that this method will only be called if the associated {@link LayoutManager}
* supports scrolling and the fling is not handled by nested scrolls first.
*
* @param velocityX the fling velocity on the X axis
* @param velocityY the fling velocity on the Y axis
*
* @return true if the fling washandled, false otherwise.
*/
public abstract boolean onFling(int velocityX, int velocityY);
}
//当前滑动距离
private int offsetY = 0;
private int offsetX = 0;
//按下屏幕点
private int startY = 0;
private int startX = 0;
//最后一个可见 view 位置
private int lastItemPosition = -1;
//第一个可见view的位置
private int firstItemPosition = -2;
//总 itemView 数量
private int totalNum;
@Override
public boolean onFling(int velocityX, int velocityY) {
if (mOrientation == ORIENTATION.NULL) {
return false;
}
//获取开始滚动时所在页面的index
int page = getStartPageIndex();
//记录滚动开始和结束的位置
int endPoint = 0;
int startPoint = 0;
//如果是垂直方向
if (mOrientation == ORIENTATION.VERTICAL) {
//开始滚动位置,当前开始执行 scrollBy 位置
startPoint = offsetY;
if (velocityY < 0) {
page--;
} else if (velocityY > 0) {
page++;
} else if (pageNum != -1) {
if (lastItemPosition + 1 == totalNum) {
mRecyclerView.scrollToPosition(0);
}
page = pageNum - 1;
}
//更具不同的速度判断需要滚动的方向
//一次滚动一个 mRecyclerView 高度
endPoint = page * mRecyclerView.getHeight();
} else {
startPoint = offsetX;
if (velocityX < 0) {
page--;
} else if (velocityX > 0) {
page++;
} else if (pageNum != -1) {
if (lastItemPosition + 1 == totalNum) {
mRecyclerView.scrollToPosition(0);
}
page = pageNum - 1;
}
endPoint = page * mRecyclerView.getWidth();
}
//使用动画处理滚动
if (mAnimator == null) {
mAnimator = 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;
if (dy == 0) return;
//这里通过RecyclerView的scrollBy方法实现滚动。
mRecyclerView.scrollBy(0, dy);
} else {
int dx = nowPoint - offsetX;
mRecyclerView.scrollBy(dx, 0);
}
}
});
mAnimator.addListener(new AnimatorListenerAdapter() {
//动画结束
@Override
public void onAnimationEnd(Animator animation) {
//回调监听
if (null != mOnPageChangeListener) {
mOnPageChangeListener.onPageChange(getPageIndex());
}
//滚动完成,进行判断是否滚到头了或者滚到尾部了
RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager();
//判断是当前layoutManager是否为LinearLayoutManager
// 只有LinearLayoutManager才有查找第一个和最后一个可见view位置的方法
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearManager = (LinearLayoutManager) layoutManager;
//获取最后一个可见view的位置
lastItemPosition = linearManager.findLastVisibleItemPosition();
//获取第一个可见view的位置
firstItemPosition = linearManager.findFirstVisibleItemPosition();
}
totalNum = mRecyclerView.getAdapter().getItemCount();
if (totalNum == lastItemPosition + 1) {
updateLayoutManger();
}
if (firstItemPosition == 0) {
updateLayoutManger();
}
}
});
} else {
mAnimator.cancel();
mAnimator.setIntValues(startPoint, endPoint);
}
mAnimator.start();
return true;
}
}
public abstract static class OnScrollListener {
/**
* Callback method to be invoked when RecyclerView's scroll state changes.
*
* @param recyclerView The RecyclerView whose scroll state has changed.
* @param newState The updated scroll state. One of {@link #SCROLL_STATE_IDLE},
* {@link #SCROLL_STATE_DRAGGING} or {@link #SCROLL_STATE_SETTLING}.
*/
public void onScrollStateChanged(RecyclerView recyclerView, int newState){}
/**
* Callback method to be invoked when the RecyclerView has been scrolled. This will be
* called after the scroll has completed.
* <p>
* This callback will also be called if visible item range changes after a layout
* calculation. In that case, dx and dy will be 0.
* 滚动完成调用
* @param recyclerView The RecyclerView which scrolled.
* @param dx The amount of horizontal scroll.
* @param dy The amount of vertical scroll.
*/
public void onScrolled(RecyclerView recyclerView, int dx, int dy){}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
//如果滑动停止
if (newState == RecyclerView.SCROLL_STATE_IDLE && mOrientation != ORIENTATION.NULL) {
boolean move;
int vX = 0, vY = 0;
if (mOrientation == ORIENTATION.VERTICAL) {
int absY = Math.abs(offsetY - startY);
//如果滑动的距离超过屏幕的一半表示需要滑动到下一页
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) {
//滚动结束记录滚动的偏移量
//记录当前滚动到的位置
offsetY += dy;
offsetX += dx;
}
}
if (mAnimator == null) {
mAnimator = 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;
if (dy == 0) return;
//这里通过RecyclerView的scrollBy方法实现滚动。
mRecyclerView.scrollBy(0, dy);
} else {
int dx = nowPoint - offsetX;
mRecyclerView.scrollBy(dx, 0);
}
}
});
public void setPageNum(int page) {
this.pageNum = page;
mOnFlingListener.onFling(0, 0);
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有