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);
                }
            }
        });
    }

}

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 Kotlin 中使用 RecyclerView 实现左滑删除 item 的代码实现: 1. 在 RecyclerView 的 item 布局文件中添加一个滑动删除的按钮,例如使用 ImageButton 实现: ```xml <ImageButton android:id="@+id/btn_delete" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="@color/colorAccent" android:padding="16dp" android:src="@drawable/ic_delete" /> ``` 2. 在 RecyclerView 的 ViewHolder 中设置按钮的点击事件,并定义一个接口用于回调删除事件: ```kotlin class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(item: MyItem, listener: OnItemClickListener) = with(itemView) { // 绑定 item 数据 // ... // 设置删除按钮点击事件 btn_delete.setOnClickListener { listener.onDeleteClick(adapterPosition) } } } interface OnItemClickListener { fun onDeleteClick(position: Int) } ``` 3. 在 RecyclerView 的 Adapter 中实现删除事件的回调: ```kotlin class MyAdapter(private val items: List<MyItem>, private val listener: OnItemClickListener) : RecyclerView.Adapter<MyViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_my, parent, false) return MyViewHolder(view) } override fun getItemCount() = items.size override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.bind(items[position], listener) } fun deleteItem(position: Int) { // 删除数据 // ... // 刷新界面 notifyItemRemoved(position) } } ``` 4. 在 Activity 或 Fragment 中实现删除事件的具体操作: ```kotlin class MyActivity : AppCompatActivity(), OnItemClickListener { private lateinit var adapter: MyAdapter private lateinit var recyclerView: RecyclerView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_my) // 初始化 RecyclerView 和 Adapter recyclerView = findViewById(R.id.recycler_view) adapter = MyAdapter(getMyItems(), this) recyclerView.adapter = adapter // 设置 RecyclerView左滑删除功能 val swipeHandler = object : SwipeToDeleteCallback(this) { override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { val position = viewHolder.adapterPosition adapter.deleteItem(position) } } val itemTouchHelper = ItemTouchHelper(swipeHandler) itemTouchHelper.attachToRecyclerView(recyclerView) } override fun onDeleteClick(position: Int) { // 在这里实现删除 item 的具体操作,例如弹出确认对话框等 // ... // 删除 item adapter.deleteItem(position) } } ``` 以上就是使用 Kotlin 实现 RecyclerView 左滑删除 item 的代码实现。注意,其中使用了 SwipeToDeleteCallback 类来实现左滑删除功能,这个类需要自己实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值