Android 自定义仿手机QQ横向滑动的RecyclerView

Android 自定义仿手机QQ横向滑动的RecyclerView

在我们的项目中,需要对列表的数据进行人性化的编辑查看与删除,与我一起工作的前辈写下了这些代码,在充分理解学习之后,我想将它保存在这里,并新增添加了注释。方便日后的使用和加深理解并希望能帮到更多的人.


/**
 * Created by dly 
 */
public class RemoveRecyclerView extends RecyclerView{
   //上一次的触摸点
   private int mLastX,mLastY;
   //当前触摸的item的位置
   private int mPostion;

   //item所对应的布局
   private LinearLayout mItemLayout;
   //删除按钮,编辑按钮在同一个Layout下
   private LinearLayout mLayoutItem;
   private TextView mDelete;
   private TextView mApproval;

   //最大滑动距离(即两个按钮的宽度)
   private int mMaxLength;
   //是否在进行垂直滑动操作
   private boolean isDragging;
   //item 是否在跟随手指移动
   private boolean isItemMoving;

   //item是否开始自动滑动
   private boolean isStartScroll;
   //按钮状态 0 关闭 1将要关闭 2将要打开 3打开
   private int mDeleteBtnState;
	
	/**
	 * VelocityTracker 是一个专用的速度追踪对象
	 */
	private VelocityTracker mVelocityTracker;
	private Scroller mScroller;
	//定义一个点击事件监听器
	private OnItemClickListener mListener;

    private boolean isSupportRemove = true;


   //三个构造方法
   public RemoveRecylerView(Context context){this(context,null);}
   
   public RemoveRecyclerView(Context context,AttributeSet attrs){
      this(context,attrs,0);
      }

   public RemoveRecyclerView(Context context,AttributeSet attrs,int defStyle){
      super(context,attrs,defStyle);
      mContext = context;
      mScroller = new Scroller(context, new LinearInterpolator());
      mVelocityTracker = VelocityTracker.obtain();
   }
   
   //重点来了: 重写触摸动作的回调方法,这里没有去写事件分发dispathevent 而是直接重写ontouchevent方法 比在网上找的其他解决方案更加简洁


/**
return true: 标识该事件处理方法已完全处理该方法,该事件不会传播出去; 
return false: 标识该事件处理方法未完全处理该方法, 该事件还会传播出去; 
**/
   @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(mDeleteBtnState == 0{
                 //RecyclerView所特有的方法,返回当前位置的item view
                 View view = findChildViewUnder(x,y);
                 if(view == null){
                   return false;
                 }
         BaseViewHolder viewHolder = (BaseViewHolder)getChildViewHolder(view);

         mItemLayout = viewHolder.getLayout();
         mPosition = viewHolder.getAdapterPosition();
         if(mItemLayout == null) return true;

    mLayoutItme = (LinearLayout) mItemLayout.findViewById(R.id.layout_click);
    mDelete = (TextView) mItemLayout.findViewById(R.id.leave_delete);
    mApproval = (TextView) mItemLayout.findViewById(R.id.leave_approval);
    mMaxLength = mLayoutItme.getWidth();

    //对textView添加点击事件
    mApprove.setOnClickListener(new OnClickListenr(){
       @Override
       public void onClick(View v){
       if(mListener == null)return;
       mListener.onApprovalClick(mPosition);
       //点击事件完成后 将item归位 并将状态值归0
       mItemLayout.scrollTo(0,0);
       mDeleteBtnState = 0;
       }
    });

     mDelete.setOnClickListener(new OnClickListener(){
     @Override
          public void onClick(View v) {
          if (mListener == null) return;
          mListener.onDeleteClick(mPosition);
          mItemLayout.scrollTo(0, 0);
          mDeleteBtnState = 0;
         }
      });
    }else if(mDeleteBtnState == 3){
       mScroller.startScroll(mItemLayout.getScrollX()0-mMaxLength,0,200);
       invalidate();
       mDeleteBtnState = 0;
       return false;
       }else{
       return false;
    }

      break;

   case MotionEvent.ACTION_MOVE:
      if(!isSupportRemove()){
          return super.onTouchEvent(e);
      } 
      int dx = mLastX - x;
      int dy = mLastY - y;

      int scrollX  = mItemLayout.getScrollX();
      if(Math.abs(dx) >Math.abs(dy)){
          isItemMoving = true;
          if(scrollX + dx <= 0){
          mItemLayout.scrollTo(0,0);
          return true;
          }else if(scrollX + dx >= mMaxLength){
              mItemLayout.scrollTo(mMaxLength,0);
              return true;
          }
          mItemLayout.scrollBy(dx,0);
      }
      break;
     case MotionEvent.ACTION_UP:
       if(!isSupportRemove()){
       	retrun super.onTouchEvent(e); 
       }
       if(!isItemMoving && !isDragging && mListener!= null){
       	mListener.onItemClick(mItemLayout,mPosition); 
     }
       isItemMoving = false;

	   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){
			deltaX = mMaxLength - upScrollX;
			mDeleteBtnState = 2;
			}else if(xVelocity > 100){
			deltaX = -upScrollX;
			mDeleteBtnState = 1;		
}
}else{
	if(upScrollX >= mMaxLength / 2){
	deltaX = mMaxLength - upScrollX;
	mDeleteBtnState = 1;
}
}else{
	if(upScrollX >= mMaxLength/2){
	   deltaX = mMaxLength - upScrollX;
	   mDeleteBtnState = 2;
	} else if(upScrollX < mMaxLength /2 ){
		deltaX = -upScrollX;
		mDeleteBtnState = 1;

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

 mVelocityTracker.clear();
 break;
      }

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



@Override
public void computeScroll(){
	if(mScroller.computeScrollOffset()){
	   mItemLayout.scrollerTo(mScroller.getCurrX(),mScroller.getCurrY());
invalidate();
	}else if(isStartScroll){
     isStartScroll = false;
     if(mDeleteBtnState == 1) {
        mDeleteBtnState = 0;
     }
     if(mDeleteBtnState == 2){
        mDeleteBtnState = 3;
        }
    } 	
}

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

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

public void setOnItemClickListener(OnItemClickListenr listener){mListener = listener;)

public boolean isSupportRemove() {return isSupportRemove;}

public void setSupportRemove(boolean supportRemove){isSupportRemove = supportRemove;}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值