Android recyclerView items的侧滑删除以及点击事件处理

最近项目中需要实现银行卡侧滑删除以及选择默认无法删除的效果,需求效果图如下:

Android recyclerView items的侧滑删除以及点击事件处理_第1张图片
其实就是一个自定义的列表实现,这里我用的是recyclerView首先需要自定义DeleteBankRecyclerView继承RecyclerView,需要注意的是item的点击和滑动事件的处理。
代码如下:

 @Override
    public boolean onTouchEvent(MotionEvent e) {

        mVelocityTracker.addMovement(e);
        //获取当前坐标
        int x = (int) e.getX();
        int y = (int) e.getY();

        switch (e.getAction()){
            case MotionEvent.ACTION_DOWN:
                //删除图片还没打开的状态
                if (status == CLOSE) {
                    //寻找对应坐标点下的V
                    View view = findChildViewUnder(x, y);
                    if (view == null) {
                        return false;
                    }
                    //通过BankMsgViewHolder获取对应的子View,详情可以看代码
                    BankMsgListAdapter.BankMsgViewHolder viewHolder = (BankMsgListAdapter.BankMsgViewHolder) getChildViewHolder(view);

                    mItemView = viewHolder.itemView.findViewById(R.id.item_layout);
                    rlBankMsg = (RelativeLayout) viewHolder.itemView.findViewById(R.id.rl_bank_msg);//item的内容
                    ivDefaultIcon = (ImageView) viewHolder.itemView.findViewById(R.id.iv_default_icon);//默认选择框
                    mPosition = viewHolder.getAdapterPosition();
                    mDeleteView = (TextView) viewHolder.itemView.findViewById(R.id.item_delete);
                    if(isForbidSideSlip){
                        mDeleteView.setVisibility(GONE);
                    }
                    mMaxLength = mDeleteView.getWidth();

                    mDeleteView.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            //返回原点
                            mItemView.scrollTo(0,0);
                            status = CLOSE;
                            if (mListener!=null)
                                mListener.onDeleteClick(mPosition);
                        }
                    });
                    //当删除图片已经完全显示的时候
                }else if (status == OPEN){
                    //从当前view的偏移点mItemView.getScrollX(),位移-mMaxLength长度单位
                    // 时间DEFAULT_TIMEms,向左移动为正数
                    mScroller.startScroll(mItemView.getScrollX(),0,-mMaxLength,0,DEFAULT_TIME);
                    //刷新下一帧动画
                    invalidate();
                    status = CLOSE;
                    return false;
                }else {
                    return false;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                //获取上次的落点与当前的坐标之间的差值
                int dx = mLastX - x;
                int dy = mLastY - y;

                int scrollX = mItemView.getScrollX();
                //水平滑动距离大于垂直距离
                if (Math.abs(dx)>Math.abs(dy) && !isForbidSideSlip){
                    isHorMoving = true;
                    //向左滑动,直至显示删除按钮,向左滑动的最大距离不超过删除按钮的宽度
                    if (scrollX+dx>=mMaxLength){
                        mItemView.scrollTo(mMaxLength,0);
                        return true;
                        //向右滑动,直至删除按钮不显示,向右滑动的最大距离不超过初始位置
                    }else if (scrollX+dx<=0){
                        mItemView.scrollTo(0,0);
                        return true;
                    }
                    
                    //如果在图片还未完全显示的状态下,那么手指滑动多少,图片就移动多少
                    mItemView.scrollBy(dx,0);
                    //mItemView.scrollTo(dx+scrollX,0);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (!isHorMoving && !isVerMoving && mListener!=null){

                    mListener.onItemClick(mItemView,ivDefaultIcon,mPosition);
                }
                isHorMoving = false;

                mVelocityTracker.computeCurrentVelocity(1000);//计算手指滑动的速度
                float xVelocity = mVelocityTracker.getXVelocity();//水平方向速度(向左为负)
                float yVelocity = mVelocityTracker.getYVelocity();//垂直方向速度

                int upScrollX = mItemView.getScrollX();
                int deltaX = 0 ;

                //向右滑动速度为正数
                //滑动速度快的状态下抬起手指,计算所需偏移量
                if (Math.abs(xVelocity)>Math.abs(yVelocity) && Math.abs(xVelocity)>=VELOCITY && !isForbidSideSlip){
                    //向右隐藏
                    if (xVelocity >= VELOCITY){
                        deltaX = -upScrollX;
                        status = CLOSING;
                    }else if (xVelocity <= -VELOCITY){
                        deltaX = mMaxLength - upScrollX;
                        status = OPENING;
                    }
                    //滑动速度慢的状态下抬起手指,如果滑动距离大于1/2的图片宽度,计算偏移量
                    //不够的话恢复原点
                }else {
                    if(!isForbidSideSlip){
                        if (upScrollX >= mMaxLength/2){
                            deltaX = mMaxLength - upScrollX;
                            status = OPENING;
                        }else {
                            deltaX = -upScrollX;
                            status = CLOSING;
                        }
                    }

                }

                mScroller.startScroll(upScrollX,0,deltaX,0,DEFAULT_TIME);
                isStartScroll = true;
                invalidate();

                mVelocityTracker.clear();
                break;
        }
        mLastX = x;
        mLastY = y;
        return super.onTouchEvent(e);
    }

    @Override
    public void computeScroll() {
        //滚动是否完成,true表示还未完成
        if (mScroller.computeScrollOffset()){
            mItemView.scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            invalidate();
            //有滑动,并且在滑动结束的时候
        }else if (isStartScroll){
            isStartScroll = false;
            if (status == CLOSING)
                status = CLOSE;

            if (status == OPENING)
                status = OPEN;
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        mVelocityTracker.recycle();
        super.onDetachedFromWindow();
    }

    @Override
    public void onScrollStateChanged(int state) {
        super.onScrollStateChanged(state);
        isVerMoving = state == SCROLL_STATE_DRAGGING;
    }

    //禁止侧滑
    public void forbidSideSlip(){

        this.isForbidSideSlip = true;

    }


//    public void setOnItemClickListener(OnItemClickListener listener){
//        this.mListener = listener;
//    }
public void setOnItemClickListener(OnItemClickListener listener){
    this.mListener = listener;
}

    public interface OnItemClickListener {
        /**
         * item点击回调
         *
         * @param view
         * @param position
         */
        void onItemClick(View view,ImageView imageView, int position);

        /**
         * 删除按钮回调
         *
         * @param position
         */
        void onDeleteClick(int position);
    }

需要说明的是 OnItemClickListener 下面的两个方法是自定义的,为了方便对item的事件处理。
自定义view之后,就是布局当中的应用,代码如下:

 

除了主布局还需要一个adapter,去展示item的具体布局如下:

public class BankMsgListAdapter extends RecyclerView.Adapter {
    private Context mContext;
    private LayoutInflater mInflater;
    private List mList;//BankCardListBean可以根据自己要求设置
    private String num;
    private boolean isOnlySelectBankCard;

    public BankMsgListAdapter(Context context, List list,boolean isOnlySelectBankCard) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
        mList = list;
        this.isOnlySelectBankCard = isOnlySelectBankCard;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new BankMsgViewHolder(mInflater.inflate(R.layout.adapter_bank_msg_list_item,parent,false));
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        if(holder instanceof BankMsgViewHolder){
            BankCardListBean bankCardListBean = mList.get(position);
            String bankCode = bankCardListBean.getcBankCode();
            if(!StringUtils.isEmpty(bankCode)){
                int drawable = BankUtil.logoForBankCode(bankCode);
                if (drawable != 0) {
                    ((BankMsgViewHolder) holder).ivBankIcon.setImageResource(drawable);
                }
            }
            String cardNo = bankCardListBean.getcCardNo();
            if (!StringUtils.isEmpty(cardNo) && cardNo.length()>4){
                num = cardNo.substring(cardNo.length()-4,cardNo.length());
            }
            String bankName = bankCardListBean.getcBankName();
            if (!StringUtils.isEmpty(bankName)){
                ((BankMsgViewHolder)holder).tvBankName.setText(bankName + "("+ num +")");
            }

            if(isOnlySelectBankCard){
                ((BankMsgViewHolder)holder).ivDefaultIcon.setVisibility(View.GONE);
                ((BankMsgViewHolder)holder).tvWordDefault.setVisibility(View.GONE);
            }else {
                ((BankMsgViewHolder)holder).ivDefaultIcon.setVisibility(View.VISIBLE);
                ((BankMsgViewHolder)holder).tvWordDefault.setVisibility(View.VISIBLE);
                Boolean aDefault = bankCardListBean.getnDefault();
                if (aDefault){
                    ((BankMsgViewHolder)holder).ivDefaultIcon.setImageResource(R.drawable.yixuan);
                }else {
                    ((BankMsgViewHolder)holder).ivDefaultIcon.setImageResource(R.drawable.weixuan);
                }
            }


        }

    }

    @Override
    public int getItemCount() {
        return mList != null ? mList.size() : 0;
    }


    public class BankMsgViewHolder extends RecyclerView.ViewHolder {


        private final TextView itemDelete;//删除按钮
        private final ImageView ivBankIcon;//银行图标
        private final TextView tvBankName;//银行名称
        private final ImageView ivDefaultIcon;//默认图标
        private final RelativeLayout rlBankMsg;//item的内容布局
        private final TextView tvWordDefault;

        public BankMsgViewHolder(View inflate) {
            super(inflate);
            rlBankMsg = (RelativeLayout) inflate.findViewById(R.id.rl_bank_msg);
            tvBankName = (TextView) inflate.findViewById(R.id.tv_bank_name);
            ivBankIcon = (ImageView) inflate.findViewById(R.id.iv_bank_icon);
            ivDefaultIcon = (ImageView) inflate.findViewById(R.id.iv_default_icon);
            itemDelete = (TextView) inflate.findViewById(R.id.item_delete);
            tvWordDefault = (TextView) inflate.findViewById(R.id.tv_word_default);
            itemView.setTag(this);

        }
    }
    public void removeItem(int position) {
        mList.remove(position);
        notifyItemRemoved(position);
    }
}

item的具体布局:

 

        
    
    
    
    



    

然后初始化布局,实现相应的方法如下

  rc_bank_list.setOnItemClickListener(new DeleteBankRecyclerView.OnItemClickListener() {

            @Override
            public void onItemClick(View view, ImageView imageView, int position) {
           // 点击操作
            }

            @Override
            public void onDeleteClick(int position) {
             //点击删除操作,调用删除方法或接口
            }
        });

以上是实现具体功能的主要代码块,希望可以给需要的你提供一点点帮助!

你可能感兴趣的:(Android,view)