01_RecyclerView实现列表Item长按移动、左右滑动删除

本文介绍如何使用ItemTouchHelper实现RecyclerView的滑动删除和拖拽功能。具体包括不同布局下拖拽方向的设置、数据交换逻辑及UI效果调整等。

 

#1 Introduce
ItemTouchHelper是一个处理RecyclerView的滑动删除和拖拽的辅助类,RecyclerView 的item拖拽移动和滑动删除就靠它来实现。
#2 效果图
ss
#3 关键代码ItemTouchHelper
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags=0,swipeFlags=0;
if(recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager ||recyclerView.getLayoutManager() instanceof GridLayoutManager){
//网格式布局有4个方向
dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
}else if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){
//线性式布局有2个方向
dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN;
swipeFlags = ItemTouchHelper.START|ItemTouchHelper.END; //设置侧滑方向为从两个方向都可以
}
return makeMovementFlags(dragFlags,swipeFlags);//swipeFlags 为0的话item不滑动
}

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
int from=viewHolder.getAdapterPosition();
int to=target.getAdapterPosition();

String moveItem = list.get(from);
list.remove(from);
list.add(to,moveItem);//交换数据链表中数据的位置

adapter.notifyItemMoved(from,to);//更新适配器中item的位置
return true;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int from=viewHolder.getAdapterPosition();
list.remove(list.get(from));
adapter.notifyItemRemoved(from);
}

@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
viewHolder.itemView.setBackgroundColor(Color.LTGRAY);//拖拽时设置背景色为灰色
}
}

@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setBackgroundColor(getResources().getColor(R.color.colorPrimary));//拖拽停止时设置背景色为白色
}

@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
//根据item滑动偏移的值修改item透明度。screenwidth是我提前获得的屏幕宽度
viewHolder.itemView.setAlpha(1-Math.abs(dX)/viewHolder.itemView.getWidth());
}
});

itemTouchHelper.attachToRecyclerView(rv);

<think>好的,我现在需要帮助用户找到在Android 14中使用Java和XML实现RecyclerView按拖拽和滑动删除功能的详细示例和说明。首先,我得回忆一下RecyclerView的相关知识,尤其是ItemTouchHelper的使用,因为这是实现拖拽和滑动删除的关键类。 用户提到了Android 14,不过其实ItemTouchHelper的用法在较新的Android版本中变化不大,可能需要注意一些兼容性问题,但基本上API是一致的。接下来,我需要整理实现步骤,包括XML布局的创建、Adapter的编写、以及ItemTouchHelper的配置。 首先,XML部分,用户需要为RecyclerView定义布局,还有每个item的布局。可能还需要处理滑动删除时的视图,比如侧滑出现的删除按钮。然后,Adapter部分需要正常实现,可能涉及到数据列表的操作,比如删除item时更新数据源并通知Adapter。 接下来是核心部分:ItemTouchHelper。需要创建一个ItemTouchHelper.Callback的子类,重写相关方法,比如getMovementFlags()来设置拖拽和滑动的方向,onMove()处理拖拽排序,onSwiped()处理滑动删除。同时,可能需要自定义滑动时的视觉效果,比如背景颜色或图标。 用户提供的引用中提到了onSwiped()方法里调用adapter的notifyItemRemoved()和更新数据列表,这很重要,确保UI和数据同步。另外,引用3提到第三方库SwipeDelMenuLayout,但用户希望用原生实现,所以可能需要自己处理侧滑布局。 另外,按拖拽的触发可能需要设置,默认情况下,item会启动拖拽,但可能需要确认是否正确处理了触摸事件。引用2中的OnRecyclerItemClickListener可能用于处理点击和按事件,但拖拽本身是由ItemTouchHelper管理的。 需要注意的地方包括:正确实现Callback的方法,确保拖拽和滑动的方向正确,比如拖拽允许上下拖动,滑动允许左右方向。另外,数据更新时要在Adapter中正确处理,避免索引错误。 可能的问题点:在滑动删除时,如何显示删除按钮或背景?可能需要自定义item布局,在滑动时动态显示/隐藏这部分内容。或者,在onChildDraw()方法中绘制删除背景,如引用1中的示例。 现在,我需要将这些步骤整理成一个清晰的教程,分步骤说明XML和Java代码的实现,并确保代码示例正确,特别是ItemTouchHelper的使用。同时,要引用用户提供的参考文献,比如处理滑动删除时引用1的方法,以及按事件的引用2和4。 最后,检查是否涵盖了所有用户需求:Android 14环境,Java和XML实现按拖拽和滑动删除功能,并给出示例代码和说明。确保代码语法正确,特别是LaTeX格式的部分,但在这个回答中可能不需要数学公式,所以主要注意代码块和引用标识的正确使用。</think>### Android 14中实现RecyclerView按拖拽与滑动删除的步骤 #### 一、XML布局配置 1. **主布局文件** `activity_main.xml` 添加RecyclerView控件: ```xml <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent"/> ``` 2. **Item布局文件** `item_layout.xml` 定义列表项布局(含滑动删除背景): ```xml <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- 滑动时显示的删除背景 --> <LinearLayout android:id="@+id/delete_background" android:layout_width="80dp" android:layout_height="match_parent" android:background="#FF0000" android:gravity="center"> <TextView android:text="删除" android:textColor="#FFF"/> </LinearLayout> <!-- 内容区域 --> <LinearLayout android:id="@+id/item_content" android:layout_width="match_parent" android:layout_height="50dp" android:background="#FFF"> <TextView android:id="@+id/tv_item" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> </FrameLayout> ``` #### 二、Java代码实现 1. **Adapter类** ```java public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<String> dataList; public static class ViewHolder extends RecyclerView.ViewHolder { TextView tvItem; public ViewHolder(View itemView) { super(itemView); tvItem = itemView.findViewById(R.id.tv_item); } } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.tvItem.setText(dataList.get(position)); } } ``` 2. **初始化RecyclerView** ```java RecyclerView recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); MyAdapter adapter = new MyAdapter(dataList); recyclerView.setAdapter(adapter); ``` 3. **实现ItemTouchHelper** ```java ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() { @Override public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { // 设置拖拽方向(上下)和滑动方向(左) int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.LEFT; return makeMovementFlags(dragFlags, swipeFlags); } @Override public boolean onMove(@NonNull RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) { // 拖拽排序逻辑 int from = source.getAdapterPosition(); int to = target.getAdapterPosition(); Collections.swap(dataList, from, to); adapter.notifyItemMoved(from, to); return true; } @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { // 滑动删除逻辑 int pos = viewHolder.getAdapterPosition(); dataList.remove(pos); adapter.notifyItemRemoved(pos); } @Override public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { // 绘制滑动删除效果 View itemView = viewHolder.itemView; View deleteBg = itemView.findViewById(R.id.delete_background); deleteBg.setVisibility(dX < 0 ? View.VISIBLE : View.GONE); super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } }; ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback); itemTouchHelper.attachToRecyclerView(recyclerView); ``` #### 三、关键功能说明 1. **按拖拽** 默认通过`ItemTouchHelper`实现列表项自动触发拖拽操作,通过`getMovementFlags()`设置允许的移动方向[^2][^4]。 2. **滑动删除** `onSwiped()`方法处理删除逻辑时需同时更新数据源和调用`notifyItemRemoved()`保证界面同步[^1]。滑动时的视觉效果通过`onChildDraw()`动态控制删除按钮的显示[^3]。 3. **兼容性说明** 上述代码在Android 14中完全兼容,若需支持更复杂的手势(如双向滑动),可扩展`getMovementFlags()`的标记值。 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值