Android:如何结合ViewBinding使用ItemTouchHelper实现侧滑功能
RecyclerView侧滑删除适配ViewBinding后失效的问题解决
问题背景
项目中RecyclerView的CardView项原本通过ItemTouchHelper实现左滑删除的UI更新,迁移到ViewBinding后,侧滑功能完全失效。
原正常运行的ItemTouchHelper代码
public class CDAItemTouchHelper extends ItemTouchHelper.SimpleCallback { private final RecyclerItemTouchHelperListener listener; public CDAItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) { super(dragDirs, swipeDirs); this.listener = listener; } @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { if (viewHolder != null) { final View foregroundView = ((CardDetailsAdapter.ItemHolder) viewHolder).viewForeground2; getDefaultUIUtil().onSelected(foregroundView); } } }
适配ViewBinding的错误尝试代码
CdaSimpleListItemBinding cdaSimpleListItemBinding; @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { if (viewHolder != null) { if (viewHolder instanceof CardDetailsAdapter.SimpleViewHolder) { layoutInflater = LayoutInflater.from(viewHolder.itemView.getContext()); cdaSimpleListItemBinding = CdaSimpleListItemBinding.inflate(layoutInflater); final View foregroundView = cdaSimpleListItemBinding.viewForeground2; getDefaultUIUtil().onSelected(foregroundView); } } }
相关配套代码
CardDetailsActivity代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding5 = ActivityDetailsBinding.inflate(getLayoutInflater()); View view5 = binding5.getRoot(); setContentView(view5); ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new CDAItemTouchHelper( 0, ItemTouchHelper.LEFT,this); new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(mRecyclerView); }
CardDetailsAdapter代码
@NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); binding6 = CdaSimpleListItemBinding.inflate(layoutInflater,parent,false); return new SimpleViewHolder(binding6); } public class SimpleViewHolder extends RecyclerView.ViewHolder { final CdaSimpleListItemBinding binding6; public SimpleViewHolder(@NonNull CdaSimpleListItemBinding binding) { super(binding.getRoot()); this.binding6 = binding; } }
cda_simple_list_item.xml布局核心代码
<FrameLayout xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_height="wrap_content" android:layout_width="match_parent" card_view:cardBackgroundColor="@android:color/white" android:foreground="?android:attr/selectableItemBackground" android:background="#FFFFFF" tools:context=".CardDetailsActivity"> <RelativeLayout android:id="@+id/view_background2" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/leave_behind_background" > ... </RelativeLayout> <RelativeLayout android:id="@+id/view_foreground2" android:layout_height="wrap_content" android:layout_width="match_parent" android:background="@color/colorFlLabelFinal" > ... </RelativeLayout> </FrameLayout>
问题根源
在适配ViewBinding的代码中,你重新inflate了一个全新的CdaSimpleListItemBinding实例,这个实例对应的View并没有被添加到RecyclerView的列表项中,ItemTouchHelper操作的是一个完全无关的View,自然无法触发原有的侧滑UI更新效果。
正确的做法是直接从ViewHolder中获取已经绑定好的Binding对象——你的SimpleViewHolder已经持有了列表项对应的Binding实例。
修正后的ItemTouchHelper代码
@Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { if (viewHolder != null) { if (viewHolder instanceof CardDetailsAdapter.SimpleViewHolder) { // 直接从ViewHolder中获取已绑定的Binding对象 CardDetailsAdapter.SimpleViewHolder holder = (CardDetailsAdapter.SimpleViewHolder) viewHolder; final View foregroundView = holder.binding6.viewForeground2; getDefaultUIUtil().onSelected(foregroundView); } } }
额外注意事项
- 确保你的
ItemTouchHelper还实现了onSwiped方法(原代码未展示),完成数据删除和Adapter更新,否则侧滑后数据不会同步删除:
@Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { if (viewHolder instanceof CardDetailsAdapter.SimpleViewHolder) { int position = viewHolder.getAdapterPosition(); // 通知listener处理删除逻辑 listener.onSwiped(viewHolder, direction, position); } }
- 确认
RecyclerItemTouchHelperListener的回调中正确调用了Adapter的notifyItemRemoved或相关更新方法,保证UI和数据同步。
内容的提问来源于stack exchange,提问作者AJW
相关产品推荐
相关产品推荐

