先看效果:
可侧滑删除修改的的 SlideRecyclerView ,继承Recycler View,重写 onTouchEvent方法
public class SlideRecyclerView extends RecyclerView {
private String TAG = "SlideRecyclerView";
private int mMaxScrollWidth;
private boolean isRlvScrolling;
private int lastRlvScrollState;
private boolean isItemStartScroll;
private VelocityTracker mVelocityTracker;
private Scroller mScroller;
private int mItemState;//0:关闭,1:将要关闭,2:将要打开,3:打开
private View mItemLayout;
private int downX=0;
private int downY=0;
private boolean isItemEnterMoving;
private int mPosition;
private int lastX ;
private int lastY ;
private OnItemClickListener onItemClickListener;
private int lastOperatePositon;
private boolean isMoved;
private int deleteWidth;
private int updateWidth;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public SlideRecyclerView(Context context) {
super(context);
init();
}
public SlideRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public SlideRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
mVelocityTracker = VelocityTracker.obtain();
mScroller = new Scroller(getContext());
}
@Override
public boolean onTouchEvent(MotionEvent e) {
mVelocityTracker.addMovement(e);
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
isMoved = false;
isItemEnterMoving = false;
downX = (int) (e.getX() + 0.5f);
downY = (int) (e.getY() + 0.5f);
lastX = downX;
lastY = downY;
View view = findChildViewUnder(downX, downY);
if (view == null) {
return false;
}
ViewHolder viewHolder = getChildViewHolder(view);
//首先获取位置
mPosition = viewHolder.getAdapterPosition();
//关闭状态
if (mItemState == 0) {
mItemLayout = view;
updateWidth = mItemLayout.findViewById(R.id.view_item_update).getWidth();
deleteWidth = mItemLayout.findViewById(R.id.view_item_delete).getWidth();
mMaxScrollWidth = updateWidth + deleteWidth;
//在这里其他状态统统关闭,不然会导致还没关闭就出现点击事件(h)
} else if (mItemState == 3 || mItemState == 2 || mItemState == 1) {
//如果点击的不是上一个,就关闭上一个
if (lastOperatePositon != mPosition){
mScroller.startScroll(mItemLayout.getScrollX(), 0, /*-mMaxScrollWidth*/ 0 -mItemLayout.getScrollX(), 0, 400);
invalidate();
mItemState = 0;
return false;//防止走UP 事件,防止响应点击事件
}else {
//return true 继续调用onTouchEvent
return true;
}
}
break;
case MotionEvent.ACTION_MOVE:
int currX = (int) (e.getX() + 0.5f);
int currY = (int) (e.getY() + 0.5f);
//移动距离
int moveX = currX - downX;
int moveY = currY - downY;
int dx = currX - lastX;
int dy = currY - lastY;
//移动了就不响应点击事件
if (Math.abs(moveX) >16 || Math.abs(moveY) > 16){
isMoved = true;
}
if (Math.abs(moveX) > Math.abs(moveY)) {
isItemEnterMoving = true;
}
int scrollX = mItemLayout.getScrollX();
Log.d(TAG, "onTouchEvent: @@@@@@ ACTION_MOVE isRlvScrolling = " + isRlvScrolling);
Log.d(TAG, "onTouchEvent: @@@@@@ ACTION_MOVE isItemEnterMoving= " + isItemEnterMoving );
if(isItemEnterMoving && !isRlvScrolling){
if (scrollX - dx >= mMaxScrollWidth) {//防止左滑过多
mItemLayout.scrollTo(mMaxScrollWidth, 0);
lastX = currX;
lastY = currY;
return true;
} else if (scrollX - dx <= 0) {//防止右滑过多
mItemLayout.scrollTo(0, 0);
lastX = currX;
lastY = currY;
return true;
}
Log.d(TAG, "onTouchEvent: scrollX = " + scrollX );
Log.d(TAG, "onTouchEvent: -dx = " + (-dx ) );
mItemLayout.scrollBy(-dx, 0);//item跟随手指滑动
Log.d(TAG, "onTouchEvent: scrollX New = " + mItemLayout.getScrollX() );
lastX = currX;
lastY = currY;
return true;
}
break;
case MotionEvent.ACTION_UP:
lastOperatePositon = mPosition;
if (isRlvScrolling){
return super.onTouchEvent(e);
}
mVelocityTracker.computeCurrentVelocity(1000);//计算手指滑动的速度
float xVelocity = mVelocityTracker.getXVelocity();//水平方向速度(向左为负)
// float yVelocity = mVelocityTracker.getYVelocity();//垂直方向速度
int deltaX = 0;
int upScrollX = mItemLayout.getScrollX();
if (Math.abs(xVelocity) > 100 /*&& Math.abs(xVelocity) > Math.abs(yVelocity)*/) {
if (xVelocity <= -100) {//左滑速度大于100,则打开item
deltaX = mMaxScrollWidth - upScrollX;
mItemState = 2;
} else if (xVelocity > 100) {//右滑速度大于100,则关闭item
deltaX = -upScrollX;
mItemState = 1;
}
} else {
if (upScrollX >= mMaxScrollWidth / 2) {//item的左滑动距离大于侧滑View宽度的一半,则打开item
deltaX = mMaxScrollWidth - upScrollX;
mItemState = 2;
} else if (upScrollX < mMaxScrollWidth / 2) {//否则隐藏
deltaX = -upScrollX;
mItemState = 1;
}
}
//item自动滑动到指定位置
mScroller.startScroll(upScrollX, 0, deltaX, 0, 400);
isItemStartScroll = true;
invalidate();
mVelocityTracker.clear();
//点击事件
int x = (int) (e.getX()+0.5f);
//&& isMoved 移动的情况下不响应点击事件
if (null != onItemClickListener && !isMoved){
if (0 == mItemLayout.getScrollX()){
onItemClickListener.onItemClick(mItemLayout,mPosition);
}else if (mMaxScrollWidth == mItemLayout.getScrollX()){
if (x >=0 && x < getWidth() - mMaxScrollWidth){
onItemClickListener.onItemClick(mItemLayout,mPosition);
}else if (x>= getWidth() - mMaxScrollWidth && x < getWidth() - deleteWidth){
onItemClickListener.onUpdateClick(mItemLayout,mPosition);
}else if (x >= getWidth() - deleteWidth && x<=getWidth()){
onItemClickListener.onDeleteClick(mItemLayout,mPosition);
}
}
}
break;
}
return super.onTouchEvent(e);
}
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
mItemLayout.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
} else if (isItemStartScroll) {
isItemStartScroll = false;
if (mItemState == 1) {
mItemState = 0;
}
if (mItemState == 2) {
mItemState = 3;
}
}
}
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
isRlvScrolling = (state == SCROLL_STATE_DRAGGING && lastRlvScrollState == SCROLL_STATE_IDLE);
lastRlvScrollState= state;
}
public interface OnItemClickListener {
void onDeleteClick(View itemView, int position);
void onUpdateClick(View itemView, int position);
void onItemClick(View itemView, int position);
}
}
item 布局文件:
使用:
布局文件中使用
点击事件:
recyclerview.setOnItemClickListener(new SlideRecyclerView.OnItemClickListener() {
@Override
public void onDeleteClick(View itemView, int position) {
Toast.makeText(CustomViewActivity.this,"删除",Toast.LENGTH_SHORT).show();
}
@Override
public void onUpdateClick(View itemView, int position) {
Toast.makeText(CustomViewActivity.this,"修改",Toast.LENGTH_SHORT).show();
}
@Override
public void onItemClick(View itemView, int position) {
Toast.makeText(CustomViewActivity.this,"内容",Toast.LENGTH_SHORT).show();
}
});
参考博客:https://www.jianshu.com/p/9bfed6e127cc