QQ側滑刪除效果 RecyclerView側滑刪除 ,修改

先看效果:

效果圖

可側滑刪除修改的的 SlideRecyclerView ,繼承Recycler View,重寫 onTouchEvent方法

public class SlideRecyclerView extends RecyclerView {
    private String TAG = "SlideRecyclerView";
    private int mMaxScrollWidth;
    private boolean isRlvScrolling;
    private int lastRlvScrollState;
    private boolean isItemStartScroll;
    private VelocityTracker mVelocityTracker;
    private Scroller mScroller;
    private int mItemState;//0:關閉,1:將要關閉,2:將要打開,3:打開
    private View mItemLayout;

    private int downX=0;
    private int downY=0;
    private boolean isItemEnterMoving;
    private int mPosition;
    private int lastX ;
    private int lastY ;
    private OnItemClickListener onItemClickListener;
    private int lastOperatePositon;
    private boolean isMoved;
    private int deleteWidth;
    private int updateWidth;



    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public SlideRecyclerView(Context context) {
        super(context);
        init();
    }

    public SlideRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public SlideRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init(){
        mVelocityTracker = VelocityTracker.obtain();
        mScroller  = new Scroller(getContext());
    }



    @Override
    public boolean onTouchEvent(MotionEvent e) {
        mVelocityTracker.addMovement(e);

        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isMoved = false;
                isItemEnterMoving = false;

                downX =  (int) (e.getX() + 0.5f);
                downY =  (int) (e.getY() + 0.5f);

                lastX = downX;
                lastY = downY;

                View view = findChildViewUnder(downX, downY);
                if (view == null) {
                    return false;
                }
                ViewHolder viewHolder =  getChildViewHolder(view);
                //首先獲取位置
                mPosition = viewHolder.getAdapterPosition();

                //關閉狀態
                if (mItemState == 0) {
                    mItemLayout = view;
                    updateWidth = mItemLayout.findViewById(R.id.view_item_update).getWidth();
                    deleteWidth = mItemLayout.findViewById(R.id.view_item_delete).getWidth();
                    mMaxScrollWidth = updateWidth + deleteWidth;
                    //在這裏其他狀態統統關閉,不然會導致還沒關閉就出現點擊事件(h)
                } else if (mItemState == 3 || mItemState == 2 || mItemState == 1) {
                    //如果點擊的不是上一個,就關閉上一個
                    if (lastOperatePositon != mPosition){
                        mScroller.startScroll(mItemLayout.getScrollX(), 0, /*-mMaxScrollWidth*/ 0 -mItemLayout.getScrollX(), 0, 400);
                        invalidate();
                        mItemState = 0;
                        return false;//防止走UP 事件,防止響應點擊事件
                    }else {
                        //return true 繼續調用onTouchEvent
                        return true;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                int currX = (int) (e.getX() + 0.5f);
                int currY = (int) (e.getY() + 0.5f);
                //移動距離
                int moveX = currX - downX;
                int moveY = currY - downY;

                int dx = currX - lastX;
                int dy = currY - lastY;
                //移動了就不響應點擊事件
                if (Math.abs(moveX) >16 || Math.abs(moveY) > 16){
                    isMoved = true;
                }

                if (Math.abs(moveX) > Math.abs(moveY)) {
                    isItemEnterMoving = true;
                }

                int scrollX = mItemLayout.getScrollX();
                Log.d(TAG, "onTouchEvent: @@@@@@ ACTION_MOVE isRlvScrolling = " + isRlvScrolling);
                Log.d(TAG, "onTouchEvent: @@@@@@ ACTION_MOVE isItemEnterMoving= " + isItemEnterMoving  );
                if(isItemEnterMoving && !isRlvScrolling){
                    if (scrollX - dx >= mMaxScrollWidth) {//防止左滑過多
                        mItemLayout.scrollTo(mMaxScrollWidth, 0);
                        lastX = currX;
                        lastY = currY;
                        return true;
                    } else if (scrollX - dx <= 0) {//防止右滑過多
                        mItemLayout.scrollTo(0, 0);
                        lastX = currX;
                        lastY = currY;
                        return true;
                    }
                    Log.d(TAG, "onTouchEvent: scrollX = " + scrollX  );
                    Log.d(TAG, "onTouchEvent: -dx = " + (-dx ) );
                    mItemLayout.scrollBy(-dx, 0);//item跟隨手指滑動
                    Log.d(TAG, "onTouchEvent: scrollX New = " + mItemLayout.getScrollX()  );
                    lastX = currX;
                    lastY = currY;
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                lastOperatePositon = mPosition;
                if (isRlvScrolling){
                    return super.onTouchEvent(e);
                }
                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) {//左滑速度大於100,則打開item
                        deltaX = mMaxScrollWidth - upScrollX;
                        mItemState = 2;
                    } else if (xVelocity > 100) {//右滑速度大於100,則關閉item
                        deltaX = -upScrollX;
                        mItemState = 1;
                    }
                } else {
                    if (upScrollX >= mMaxScrollWidth / 2) {//item的左滑動距離大於側滑View寬度的一半,則打開item
                        deltaX = mMaxScrollWidth - upScrollX;
                        mItemState = 2;
                    } else if (upScrollX < mMaxScrollWidth / 2) {//否則隱藏
                        deltaX = -upScrollX;
                        mItemState = 1;
                    }
                }

                //item自動滑動到指定位置
                mScroller.startScroll(upScrollX, 0, deltaX, 0, 400);
                isItemStartScroll = true;
                invalidate();
                mVelocityTracker.clear();

                //點擊事件
                int x = (int) (e.getX()+0.5f);
                //&& isMoved   移動的情況下不響應點擊事件
                if (null != onItemClickListener && !isMoved){
                    if (0 == mItemLayout.getScrollX()){
                        onItemClickListener.onItemClick(mItemLayout,mPosition);
                    }else if (mMaxScrollWidth == mItemLayout.getScrollX()){
                        if (x >=0 && x < getWidth() - mMaxScrollWidth){
                            onItemClickListener.onItemClick(mItemLayout,mPosition);
                        }else if (x>= getWidth() - mMaxScrollWidth && x < getWidth() - deleteWidth){
                            onItemClickListener.onUpdateClick(mItemLayout,mPosition);
                        }else if (x >= getWidth() - deleteWidth && x<=getWidth()){
                            onItemClickListener.onDeleteClick(mItemLayout,mPosition);
                        }
                    }
                }
                break;
        }
        return super.onTouchEvent(e);
    }

    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            mItemLayout.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        } else if (isItemStartScroll) {
            isItemStartScroll = false;
            if (mItemState == 1) {
                mItemState = 0;
            }
            if (mItemState == 2) {
                mItemState = 3;
            }
        }
    }

    public void onScrollStateChanged(int state) {
        super.onScrollStateChanged(state);
        isRlvScrolling = (state == SCROLL_STATE_DRAGGING  &&  lastRlvScrollState == SCROLL_STATE_IDLE);
        lastRlvScrollState= state;
    }
    public interface OnItemClickListener {
        void onDeleteClick(View itemView, int position);
        void onUpdateClick(View itemView, int position);
        void onItemClick(View itemView, int position);
    }
}

 

 

item 佈局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#660000ff"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="100dp">

    <TextView
        android:id="@+id/textview"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/view_item_update"
        android:textSize="20dp"
        android:textColor="#ffffff"
        android:text="修改"
        android:gravity="center"
        android:background="@color/colorPrimaryDark"
        android:layout_width="80dp"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/view_item_delete"
        android:textSize="20dp"
        android:text="刪除"
        android:gravity="center"
        android:textColor="#ffffff"
        android:background="@color/colorAccent"
        android:layout_width="80dp"
        android:layout_height="match_parent" />




</LinearLayout>

使用:

佈局文件中使用
<com.example.myapplication1.view.SlideRecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </com.example.myapplication1.view.SlideRecyclerView>

點擊事件:
recyclerview.setOnItemClickListener(new SlideRecyclerView.OnItemClickListener() {
            @Override
            public void onDeleteClick(View itemView, int position) {
                Toast.makeText(CustomViewActivity.this,"刪除",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onUpdateClick(View itemView, int position) {
                Toast.makeText(CustomViewActivity.this,"修改",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onItemClick(View itemView, int position) {
                Toast.makeText(CustomViewActivity.this,"內容",Toast.LENGTH_SHORT).show();
            }
        });

參考博客:https://www.jianshu.com/p/9bfed6e127cc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章