You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:24:57