RecyclerView配合ItemTouchHelper的使用

temTouchHelper,可以很好的处理RecyclerView的item的滑动拖拽功能。
ItemTouchHelper是android.support.v7.widget.helper包中的一个类,但现在android官方文档搜索,你会发现有两个ItemTouchHelper,其中是这个包下,另一个是androidx.recyclerview.widget包下的,根据官网说法androidx是新推出的软件包结构,一些support包都向androidx下迁移。不过现在support现在还是可以用的,Google给开发者一定的迁移时间。
在这里插入图片描述
ItemTouchHelper的构造方法需要传入ItemTouchHelper.Callback来实现对拖拽的监听。
现在就来看看ItemTouchHelper.Callback的一些方法
ItemTouchHelper.Callback是一个抽象类或者匿名内部类实现它,都必须实现它下面几个抽象方法

//拖拽的标志
 public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
 //移动的监听
 public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
 // 滑动的回调
 public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction)
简单的使用

长按可以进行拖拽交换位置,左右可以滑动删除
在这里插入图片描述

适配器代码

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
    private ArrayList<String> lists;

    public RecyclerViewAdapter(ArrayList<String> lists) {
        this.lists = lists;
    }
    
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle, parent, false);
        return new MyViewHolder(view);
    }
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.tv.setText(lists.get(position));
    }

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


    /** 删除数据
     * @param position
     */
    public final void delData(int position) {
        lists.remove(position);
        notifyItemRemoved(position);
    }

    /** 移动进行数据交换
     * @param fromPosition 
     * @param toPosition
     */
    public final void move(int fromPosition, int toPosition) {
        Collections.swap(lists, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
    }
    
    class MyViewHolder extends RecyclerView.ViewHolder {
         AppCompatTextView tv;

        private MyViewHolder(View itemView) {
            super(itemView);
            tv = itemView.findViewById(R.id.tv);
        }
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private RecyclerViewAdapter recyclerViewAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = findViewById(R.id.recycler_view);
        //模拟数据
        ArrayList<String> lists = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            lists.add("item" + i);
        }
        recyclerViewAdapter = new RecyclerViewAdapter(lists);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(recyclerViewAdapter);
        final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            /**
             *
             * @param recyclerView 关联的recyclerView
             * @param viewHolder  操作的viewHolder对象
             * @return 返回运动方向标志的组合,通过makeMovementFlags(dragFlags, swipeFlags)进行组合
             */
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                //拖拽的方法标记
                int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
                //滑动方向标记
                int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
                //通过makeMovementFlags方法将将方向标记进行组合,并将复合的值返回
                return makeMovementFlags(dragFlags, swipeFlags);
            }

            /**
             * @param recyclerView 关联的recyclerView
             * @param viewHolder  要移动的viewHolder对象
             * @param target   移动到的目标ViewHolder对象
             * @return 返回true 才会执行ItemTouchHelper.Callback的onMoved方法,
             */
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                recyclerViewAdapter.move(viewHolder.getAdapterPosition(), target.getAdapterPosition());
                return true;
            }

            /**
             * @param viewHolder 滑动的viewHolder对象
             * @param direction  移动的方向标识
             */
            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                recyclerViewAdapter.delData(viewHolder.getAdapterPosition());
            }
        });
	    //关联RecyclerView
        itemTouchHelper.attachToRecyclerView(recyclerView);
    }
}
如果想操作item条目是想让条目高亮怎么办,如下面效果?

在这里插入图片描述
想实现这种效果就要重写ItemTouchHelper.Callback的两个方法

// 拖拽或者滑动时调用
 public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)
 //拖拽或者滑动结束后调用
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) 

具体实现

            /**
             * @param viewHolder  操作的ViewHolder对象
             * @param actionState  当前的状态, ItemTouchHelper.ACTION_STATE_IDLE,闲置状态
             *                     ItemTouchHelper.ACTION_STATE_SWIPE,开始滑动状态
             *                     ItemTouchHelper.ACTION_STATE_DRAG,开始拖拽
             */
            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                //如果不是现实状态
                if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
                    //设置背景颜色为蓝色
                    viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getResources().getColor(android.R.color.holo_blue_light));
                    if (viewHolder instanceof RecyclerViewAdapter.MyViewHolder) {
                        RecyclerViewAdapter.MyViewHolder myViewHolder = (RecyclerViewAdapter.MyViewHolder) viewHolder;
                        //设置字体为白色
                        myViewHolder.tv.setTextColor(Color.WHITE);
                    }
                }
                super.onSelectedChanged(viewHolder, actionState);
            }

            /** 还原状态
             * @param recyclerView
             * @param viewHolder
             */
            @Override
            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                viewHolder.itemView.setBackgroundColor(Color.TRANSPARENT);
                if (viewHolder instanceof RecyclerViewAdapter.MyViewHolder) {
                    RecyclerViewAdapter.MyViewHolder myViewHolder = (RecyclerViewAdapter.MyViewHolder) viewHolder;
                    myViewHolder.tv.setTextColor(Color.BLACK);
                }
                super.clearView(recyclerView, viewHolder);
            }

上面代码可以看到在onSelectedChanged 中获得viewHolder对象,就可以对RecyclerView的条目进行一些操作,如上面背景颜色的改变,还可以设置条目的一些动画效果,当然一定要记得再clearView 还原条目的改变,否则回出现一些奇怪的情况,因为RecyclerView条目是View是复用的。

非长按拖拽效果

ItemTouchHelper 默认是长按触发拖拽,当然我们可以设置非长按拖拽效果,例如按住一个图片进行拖拽
在这里插入图片描述

实现方法
1 在适配器重写这个图片的OnTouchListener方法

 @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        holder.tv.setText(lists.get(position));
//设置holder.img 的OnTouchListener方法
        holder.img.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //dragListener 是适配器内部接口
                    if (dragListener != null) {
                        dragListener.onDrag(holder);
                    }
                }
                return false;
            }
        });
    }
 public interface DragListener {
        /**
         * 使用接口回调的方式将ViewHolder返回
         * @param holder
         */
        void onDrag(MyViewHolder holder);
    }

    private DragListener dragListener;

    public void setDragListener(DragListener dragListener) {
        this.dragListener = dragListener;
    }

2 在MainActivity中设置接口回调

 recyclerViewAdapter.setDragListener(new RecyclerViewAdapter.DragListener() {
            @Override
            public void onDrag(RecyclerViewAdapter.MyViewHolder holder) {
            // 手动的条用ItemTouchHelper的开始拖拽方法
                itemTouchHelper.startDrag(holder);
            }
        });
在Android开发中,结合RecyclerViewItemTouchHelper实现拖拽排序与侧滑删除功能,可以极大地提升用户交互体验。为了帮助你掌握这一实用技能,特别推荐《Android RecyclerView拖拽排序与侧滑删除实战》作为参考资料,其中包含了丰富的示例代码和详细解释,非常适合想要深入了解这些功能的开发者。 参考资源链接:[Android RecyclerView拖拽排序与侧滑删除实战](https://wenku.csdn.net/doc/7nd6vmz2sb) 具体实现步骤如下: 1. 首先确保你的项目中已经集成了RecyclerViewItemTouchHelper库。 2. 创建一个RecyclerView的Adapter,并在其中处理数据绑定和视图更新的逻辑。 3. 实现ItemTouchHelper.Callback的子类,比如叫做`MyItemTouchHelperCallback`。在这个类中,你需要重写几个关键的方法来定义拖拽和滑动的行为: ```java public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback { private final ItemTouchHelperAdapter mAdapter; public MyItemTouchHelperCallback(ItemTouchHelperAdapter adapter) { this.mAdapter = adapter; } @Override public boolean isItemViewSwipeEnabled() { return true; // 允许滑动删除 } @Override public boolean isLongPressDragEnabled() { return true; // 允许长按拖拽 } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; // 设置拖拽方向 final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; // 设置滑动方向 return makeMovementFlags(dragFlags, swipeFlags); // 返回拖拽和滑动标记 } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; // 返回true表示拖拽成功 } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); } } ``` 4. 在你的Activity或者Fragment中,获取RecyclerView的实例,并将ItemTouchHelper与你的Callback关联起来: ```java RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); MyAdapter adapter = new MyAdapter(); recyclerView.setAdapter(adapter); ItemTouchHelperCallback callback = new ItemTouchHelperCallback(adapter); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback); itemTouchHelper.attachToRecyclerView(recyclerView); ``` 通过以上步骤,你就可以实现基本的拖拽排序和侧滑删除功能。务必确保在Adapter的`onItemMove`方法中更新数据源和通知数据变化,在`onItemDismiss`方法中删除数据项并通知数据变化。这样可以保证数据和视图的一致性。 为了更深入地掌握这些技能,建议你阅读《Android RecyclerView拖拽排序与侧滑删除实战》,它不仅介绍了如何实现这些功能,还提供了关于如何自定义触觉反馈、动画以及其他高级功能的详细指南。这本资料非常适合想要全面理解和应用RecyclerViewItemTouchHelper的开发者使用。 参考资源链接:[Android RecyclerView拖拽排序与侧滑删除实战](https://wenku.csdn.net/doc/7nd6vmz2sb)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值