Android(安卓)recyclerView items的侧滑删除以及点击事件处理
16lz
2021-01-26
最近项目中需要实现银行卡侧滑删除以及选择默认无法删除的效果,需求效果图如下:
其实就是一个自定义的列表实现,这里我用的是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) { //点击删除操作,调用删除方法或接口 } });
以上是实现具体功能的主要代码块,希望可以给需要的你提供一点点帮助!
更多相关文章
- 布局中@null的代码实现方式
- Android中抛出android.app.Fragment$InstantiationException异常
- Android上实现一个简单的天气预报APP(二) 配置布局
- Android(安卓)学习之路3
- 简述Android六大布局
- Xamarin Android开发实战(上册)
- android ViewFilpper(一)
- Android二维码生成与扫描
- RecyclerView嵌套GridView,RecyclerView的第一个item显示不全