RecyclerView实现左滑删除功能

本章节讲述RecyclerView左滑删除功能。

 

https://blog.csdn.net/weixin_37730482/article/details/72866943

这篇文章有讲解RecyclerView有一个ItemTouchHelper工具类,该工具类有一个叫CallBack的内部静态类。其实也可实现左滑删除,但是onChildDraw方法中不好处理删除时的布局。所以本章节讲述自定义RecyclerView的方式实现左滑删除。

 

 

1.自定义View

package com.wjn.viewlistdemo.activity.recyclerview.del;

import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;

import com.wjn.viewlistdemo.R;

public class DelRecyclerView extends RecyclerView {

    private static final String TAG = "DelRecyclerView";
    private int maxLength, mTouchSlop;
    private int xDown, yDown, xMove, yMove;

    private int curSelectPosition;//当前选中的item位置
    private LinearLayout mCurItemLayout;//当前选中的item布局
    private RelativeLayout mLlHidden;//隐藏部分
    private LinearLayout mLastItemLayout;

    private int mHiddenWidth;//隐藏部分长度

    private int mMoveWidth = 0;//记录连续移动的长度

    private boolean isFirst = true;//是否是第一次touch

    private Scroller mScroller;

    /**
     * 删除的监听事件
     */

    private OnRightClickListener mRightListener;

    public void setRightClickListener(OnRightClickListener listener) {
        this.mRightListener = listener;
    }

    /**
     * 构造方法
     */

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

    /**
     * 构造方法
     */

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

    /**
     * 初始化
     */

    private void init(Context context) {
        //滑动到最小距离
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        //滑动的最大距离
        maxLength = ((int) (180 * context.getResources().getDisplayMetrics().density + 0.5f));
        //初始化Scroller
        mScroller = new Scroller(context, new LinearInterpolator(context, null));
    }

    /**
     * onTouchEvent方法
     */

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        int x = (int) e.getX();
        int y = (int) e.getY();
        switch (e.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;
                        }
                    }
                }

                if (isFirst) {//第一次时,不用重置上一次的Item
                    isFirst = false;
                } else {
                    //屏幕再次接收到点击时,恢复上一次Item的状态
                    if (mLastItemLayout != null && mMoveWidth > 0) {
                        //将Item右移,恢复原位
                        scrollRight(mLastItemLayout, (0 - mMoveWidth));
                        //清空变量
                        mHiddenWidth = 0;
                        mMoveWidth = 0;
                    }

                }

                //取到当前选中的Item,赋给mCurItemLayout,以便对其进行左移
                View item = getChildAt(curSelectPosition - firstPosition);
                if (item != null) {
                    //获取当前选中的Item
                    DelAdapter.ViewHolder viewHolder = (DelAdapter.ViewHolder) getChildViewHolder(item);
                    mCurItemLayout = viewHolder.layout;
                    //找到具体元素(这与实际业务相关了~~)
                    mLlHidden = mCurItemLayout.findViewById(R.id.recycleview_item_dellayout);
                    mLlHidden.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (mRightListener != null) {
                                //删除
                                mRightListener.onRightClick(curSelectPosition, "");
                            }
                        }
                    });
                    //这里将删除按钮的宽度设为可以移动的距离
                    mHiddenWidth = mLlHidden.getWidth();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                xMove = x;
                yMove = y;
                int dx = xMove - xDown;//为负时:手指向左滑动;为正时:手指向右滑动。这与Android的屏幕坐标定义有关
                int dy = yMove - yDown;//

                //左滑
                if (dx < 0 && Math.abs(dx) > mTouchSlop && Math.abs(dy) < 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 > 0) {//右滑
                    //执行右滑,这里没有做跟随,瞬间恢复
                    scrollRight(mCurItemLayout, 0 - mMoveWidth);
                    mMoveWidth = 0;
                }

                break;
            case MotionEvent.ACTION_UP://手抬起时
                int scrollX = mCurItemLayout.getScrollX();

                if (mHiddenWidth > mMoveWidth) {
                    int toX = (mHiddenWidth - mMoveWidth);
                    if (scrollX > mHiddenWidth / 2) {//超过一半长度时松开,则自动滑到左侧
                        scrollLeft(mCurItemLayout, toX);
                        mMoveWidth = mHiddenWidth;
                    } else {//不到一半时松开,则恢复原状
                        scrollRight(mCurItemLayout, 0 - mMoveWidth);
                        mMoveWidth = 0;
                    }
                }
                mLastItemLayout = mCurItemLayout;
                break;
        }
        return super.onTouchEvent(e);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            mCurItemLayout.scrollBy(mScroller.getCurrX(), 0);
            invalidate();
            Log.d(TAG, "computeScroll getCurrX ->" + mScroller.getCurrX());
        }
    }

    /**
     * 向左滑动
     */

    private void scrollLeft(View item, int scorllX) {
        item.scrollBy(scorllX, 0);
        Log.d(TAG, " scroll left -> " + scorllX);
    }

    /**
     * 向右滑动
     */

    private void scrollRight(View item, int scorllX) {
        item.scrollBy(scorllX, 0);
        Log.d(TAG, " scroll right -> " + scorllX);
    }

}

 

 

2.Adapter

package com.wjn.viewlistdemo.activity.recyclerview.del;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.wjn.viewlistdemo.R;
import com.wjn.viewlistdemo.activity.recyclerview.Student;
import com.wjn.viewlistdemo.activity.recyclerview.slide.SlideAdapter;

import java.util.List;

public class DelAdapter extends RecyclerView.Adapter<DelAdapter.ViewHolder> {

    private List<Student> list;
    private LayoutInflater mInflater;

    public DelAdapter(Context context, List<Student> list) {
        this.list = list;
        mInflater = LayoutInflater.from(context);
    }


    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = mInflater.inflate(R.layout.recyclerview_item, viewGroup, false);
        DelAdapter.ViewHolder holder = new DelAdapter.ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        viewHolder.textView1.setText(list.get(i).getName() + "【" + (i + 1) + "】");
        viewHolder.textView2.setText(list.get(i).getDescribe());
        viewHolder.circleImageView.setBackgroundResource(R.mipmap.patient_ava);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    /**
     * ViewHolder类
     */

    class ViewHolder extends RecyclerView.ViewHolder {

        public LinearLayout layout;
        private ImageView circleImageView;
        private TextView textView1;
        private TextView textView2;

        public ViewHolder(View itemView) {
            super(itemView);
            layout = itemView.findViewById(R.id.recycleview_item_layout);
            circleImageView = itemView.findViewById(R.id.recycleview_circleimageview);
            textView1 = itemView.findViewById(R.id.recycleview_item_textview1);
            textView2 = itemView.findViewById(R.id.recycleview_item_textview2);
        }
    }

    /**
     * 删除数据
     */

    public void removeData(int position) {
        list.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, list.size());
    }

}

 

 

3.接口

package com.wjn.viewlistdemo.activity.recyclerview.del;

public interface OnRightClickListener {

    void onRightClick(int position, String id);

}

 

 

4.使用

package com.wjn.viewlistdemo.activity.recyclerview.del;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;

import com.wjn.viewlistdemo.R;
import com.wjn.viewlistdemo.activity.recyclerview.RecyclerViewUtils;
import com.wjn.viewlistdemo.activity.recyclerview.Student;
import com.wjn.viewlistdemo.activity.recyclerview.slide.SlideAdapter;

import java.util.List;

public class DelRecyclerViewActivity extends AppCompatActivity {

    private DelRecyclerView recyclerView;
    private List<Student> list;
    private DelAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_del_recycler_view);
        initView();
    }

    /**
     * 初始化各种View
     */

    private void initView() {
        recyclerView = findViewById(R.id.activity_del_recycler_view_recyclerview);
        list = RecyclerViewUtils.getInstance().getList();
        //1.设置LinearLayoutManager ListView
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //2.设置固定大小
        recyclerView.setHasFixedSize(true);
        //3.设置Adapter
        adapter = new DelAdapter(this, list);
        recyclerView.setAdapter(adapter);
        //4.左滑删除
        initRightView(recyclerView);
    }

    private void initRightView(DelRecyclerView recyclerView) {
        if (null == recyclerView) {
            return;
        }

        recyclerView.setRightClickListener(new OnRightClickListener() {
            @Override
            public void onRightClick(int position, String id) {
                if (null != adapter) {
                    adapter.removeData(position);
                }
            }
        });
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值