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

如何在RecyclerView中按条件禁用其余列表项的onTouch触摸事件?

结论

完全可以实现该需求,共有两种常用实现方案,可根据业务场景选择:


方案1:Adapter状态控制(兼容性最好,适用大多数场景)

无需修改触摸事件分发逻辑,实现简单,还可灵活控制单个item的可用状态:

  • 在Adapter内部定义两个全局变量:锁定状态标记private boolean isItemsLocked = false、选中的item位置private int selectedPos = -1
  • 重写onBindViewHolder方法,绑定item时判断状态:如果isItemsLocked为true且当前绑定的position不等于selectedPos,调用holder.itemView.setEnabled(false),可同时设置半透明、置灰等禁用态视觉效果;如果锁定状态解除,统一将所有item的setEnabled属性恢复为true
  • 在item点击回调中加判断:如果isItemsLocked为true且当前点击的不是选中item,直接return不执行后续逻辑;如果是首次点击未锁定状态的item,将isItemsLocked设为true,记录当前点击的position,调用刷新方法更新列表状态
  • 预设条件达成需要恢复点击权限时,将isItemsLocked改回false、selectedPos重置为-1,再次刷新列表即可

方案2:RecyclerView触摸拦截(适合全局拦截所有触摸的场景)

如果需要连item内部子控件的触摸、列表滚动等操作一起拦截,可通过自定义RecyclerView实现:

  • 自定义RecyclerView重写onInterceptTouchEvent方法,内部加入锁定状态判断,锁定状态下直接返回true拦截所有触摸事件,不会向下分发给子item
  • 代码示例:
public class LockableRecyclerView extends RecyclerView {
    private boolean isTouchLocked = false;

    // 省略构造方法
    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return isTouchLocked || super.onInterceptTouchEvent(e);
    }

    public void setTouchLocked(boolean locked) {
        isTouchLocked = locked;
    }
}
  • 点击item后调用recyclerView.setTouchLocked(true)即可拦截所有后续触摸操作,条件满足后调用setTouchLocked(false)恢复

注意:该方案会拦截整个RecyclerView的所有触摸行为,包括滚动、选中item的点击操作,如果需要保留选中item的可操作权限,优先选择方案1


优化建议
  • 两种方案都可以配合禁用态UI效果提示用户,比如给不可点击的item设置0.5f的透明度,降低用户疑惑
  • 如果使用DiffUtil做局部刷新,不需要调用全量notifyDataSetChanged(),只刷新受影响的item即可,性能更优

内容的提问来源于stack exchange,提问作者Maria Luíza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:45:02