自定义无动画效果无跟随手势侧滑效果的Rv侧滑删除基础版V1.0
关于Rv侧滑删除已经看过很多大佬写的,今天自己在这里写了个自定义侧滑删除,视图xml没有补充出来了,大致就是内容这是充满activity,超出屏幕部分设置个删除按钮样式就行,布局我就不展示了,这里仅贴出侧滑删除的自定义代码。
/**
* 侧滑删除二次确认删除Recyclerview
* @author hwhu3
*/
public class SideslipRecyclerView extends RecyclerView {
private static final String TAG = "SideslipRecyclerView";
private int mTouchSlop;
private int xDown, yDown, xMove, yMove;
/**
* 当前选中的item索引
*/
private int curSelectPosition;
private int mLastSelectPosition = -1;
private Scroller mScroller;
private ViewGroup mCurItemLayout, mLastItemLayout;
//按钮布局
private LinearLayout mLlHidden;
//删除按钮
private TextView mTvDel;
private OnItemClickListener onItemClickListener;
/**
* 隐藏部分长度
*/
private int mHiddenWidth;
/**
* 记录连续移动的长度
*/
private int mMoveWidth = 0;
/**
* 是否是第一次点击
*/
private boolean isFirst = true;
private Context mContext;
private View view;
public SideslipRecyclerView(@NonNull Context context) {
this(context, null);
}
public SideslipRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public SideslipRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
//滑动到最小距离
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
//初始化Scroller
mScroller = new Scroller(context, new LinearInterpolator(context, null));
view = inflate(mContext,R.layout.item_sideslip_del,null);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = (int)ev.getX();
int y = (int)ev.getY();
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
//记录当前按下的坐标
xDown = x;
yDown = y;
//计算选中哪个Item
int firstPosition = ((LinearLayoutManager)getLayoutManager()).findFirstVisibleItemPosition();
Rect itemRect = new Rect();
final int count = getChildCount();
for (int i=0; i<count; i++){
final View child = getChildAt(i);
if (child.getVisibility() == View.VISIBLE){
child.getHitRect(itemRect);
if (itemRect.contains(x, y)){
curSelectPosition = firstPosition + i;
break;
}
}
}
//第一次时,不用重置上一次的Item
if (isFirst){
isFirst = false;
}else {
//屏幕再次接收到点击时,恢复上一次Item的状态
if (mLastItemLayout != null && mMoveWidth > 0 && mLastSelectPosition != curSelectPosition) {
//将Item右移,恢复原位
scrollRight(mLastItemLayout, (0 - mMoveWidth));
//清空变量
mHiddenWidth = 0;
mMoveWidth = 0;
}
}
//取到当前选中的Item,赋给mCurItemLayout,以便对其进行左移
View item = getChildAt(curSelectPosition - firstPosition);
//业务逻辑部分
if (item != null) {
//获取当前选中的Item
try {
mCurItemLayout = (ViewGroup) getChildViewHolder(item).itemView;
}catch (Exception exp){
}
//找到具体元素
mLlHidden = (LinearLayout)mCurItemLayout.findViewById(R.id.ll_hidden);
mTvDel = (TextView) mCurItemLayout.findViewById(R.id.tv_item_delete);
mLlHidden.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if("删除".equals(mTvDel.getText())) {
mTvDel.setText("确认删除");
Toast.makeText(mContext, "确认要删除当前条目吗?", Toast.LENGTH_SHORT).show();
}else if("确认删除".equals(mTvDel.getText())){
//处理删除前item未归位的问题
scrollRight(mCurItemLayout,(0-mMoveWidth));
mMoveWidth = 0;
if(onItemClickListener!=null){
onItemClickListener.onDeleteClick(curSelectPosition);
}
}
}
});
//业务逻辑部分终止
//这里将删除按钮的宽度设为可以移动的距离
mHiddenWidth = mLlHidden.getWidth();
//记录点击时的下标
mLastSelectPosition = curSelectPosition;
}
break;
case MotionEvent.ACTION_MOVE:
xMove = x;
yMove = y;
int dx = xMove - xDown;//为负时:手指向左滑动;为正时:手指向右滑动。
int dy = yMove - yDown;//上滑为负,下滑为正
Log.d(TAG,"dx:"+dx+"dy:"+dy+"---mMoveWidth:"+mMoveWidth+"mHiddenWidth"+mHiddenWidth);
//解决滑动事件冲突问题
if(Math.abs(dx) > Math.abs(dy)){
//左滑
if (dx < 0 && Math.abs(dx) > mTouchSlop){
int newScrollX = Math.abs(dx);
//移动距离超过可移动宽度
if (mMoveWidth >= mHiddenWidth){
newScrollX = 0;
} else if (mMoveWidth + newScrollX > mHiddenWidth){
newScrollX = mHiddenWidth - mMoveWidth;
}
//左滑,每次滑动手指移动的距离
scrollLeft(mCurItemLayout, newScrollX);
//对移动的距离叠加
mMoveWidth = mMoveWidth + newScrollX;
}else if (dx > mMoveWidth){//右滑
//执行右滑,瞬间恢复
scrollRight(mCurItemLayout, 0 - mMoveWidth);
mMoveWidth = 0;
}
return true;
}
break;
case MotionEvent.ACTION_UP://手抬起时
int scrollX = mCurItemLayout.getScrollX();
Log.d(TAG,"抬起后mMoveWidth"+mMoveWidth+"scrollX"+scrollX+"mHiddenWidth"+mHiddenWidth);
if (mHiddenWidth > mMoveWidth) {
int toX = (mHiddenWidth - mMoveWidth);
//由于移动长度较小所以不以1/2为标准计算
if (scrollX > mHiddenWidth) {
scrollLeft(mCurItemLayout, toX);
mMoveWidth = mHiddenWidth;
} else {
scrollRight(mCurItemLayout, 0 - mMoveWidth);
mMoveWidth = 0;
}
}
mLastItemLayout = mCurItemLayout;
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
public void computeScroll() {
if (!mScroller.isFinished()) {
if (mScroller.computeScrollOffset()) {
Log.e(TAG, "computeScroll getCurrX ->" + mScroller.getCurrX());
mCurItemLayout.scrollBy(mScroller.getCurrX(), 0);
invalidate();
}
}
}
/**
* 向左滑动
*/
private void scrollLeft(View item, int scorllX){
Log.e(TAG, " scroll left -> " + scorllX);
mTvDel = item.findViewById(R.id.tv_item_delete);
if(scorllX != 0 &&"确认删除".equals(mTvDel.getText().toString())) {
mTvDel.setText("删除");
}
item.scrollBy(scorllX, 0);
invalidate();
}
/**
* 向右滑动
*/
private void scrollRight(View item, int scorllX){
Log.e(TAG, " scroll right -> " + scorllX);
item.scrollBy(scorllX, 0);
invalidate();
}
/**
* 确认删除回调
*/
public interface OnItemClickListener {
/**
* 删除按钮回调
*
* @param position
*/
void onDeleteClick(int position);
}
}