RecyclerView Holder点击事件未触发问题求助
解决RecyclerView Item点击事件被TextView拦截的问题
这种子View抢占点击事件的情况我之前也碰到过,给你几个实用的解决思路,按优先级推荐:
1. 禁止TextView获取焦点
TextView默认具备获取焦点的能力,这会导致它直接拦截点击事件,无法传递到父布局。你只需要给每个TextView添加两个属性即可解决:
android:focusable="false" android:focusableInTouchMode="false"
修改后的TextView示例:
<TextView android:id="@+id/lbl_exo_name" android:layout_width="0dp" android:layout_weight="1" android:layout_height="40dp" android:gravity="center" android:textColorHint="#aeafaf" android:textSize="15dp" android:focusable="false" android:focusableInTouchMode="false" />
这个方法最简单直接,也是最常用的解决方案,亲测有效。
2. 直接给外层容器绑定点击监听
你当前是给holder.itemView设置点击,但有时候itemView的层级嵌套会导致事件传递异常。可以先给最外层的RelativeLayout添加一个id(比如android:id="@+id/item_root"),然后直接给它绑定点击事件:
@Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { // 初始化TextView等原有逻辑 RelativeLayout rootLayout = holder.itemView.findViewById(R.id.item_root); rootLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Model_NewProg model_newProg = ListOfExo.get(position); openDialog(model_newProg, position); } }); }
RelativeLayout默认android:clickable为true,不需要额外设置,这样点击整个容器区域都会触发事件。
3. 使用RecyclerView全局触摸监听
如果上面两种方法都不生效,可以试试绕过子View的事件拦截,直接用RecyclerView的全局触摸监听来处理点击:
// 在初始化RecyclerView的代码块中添加 recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { private final GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } }); @Override public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { View childView = rv.findChildViewUnder(e.getX(), e.getY()); if (childView != null && gestureDetector.onTouchEvent(e)) { int position = rv.getChildAdapterPosition(childView); Model_NewProg model_newProg = ListOfExo.get(position); openDialog(model_newProg, position); return true; } return false; } @Override public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {} @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {} });
这种方式直接通过触摸坐标判断点击的item,不受子View的事件拦截影响,适合布局结构复杂的场景。
额外检查点
- 确认RelativeLayout的
android:background="?android:attr/selectableItemBackground"设置正常,这个属性是为了提供点击波纹反馈,不会干扰事件传递,但如果父布局不可点击会失效。 - 不要给TextView设置
android:clickable="true",这会让TextView完全拦截点击事件,即使设置了focusable也无法解决。
内容的提问来源于stack exchange,提问作者ImNeos
相关产品推荐
相关产品推荐

