自定义无动画效果无跟随手势侧滑效果的Rv侧滑删除基础版V1.0

自定义无动画效果无跟随手势侧滑效果的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);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值