Android RecyclerView自身优先获焦,实现首点击子项不获焦、二次点击获焦
解决方案
要实现首次点击父布局(@+id/rll)时获取焦点并阻止RecyclerView子项获焦,第二次点击允许子项正常获焦,核心是动态调整父布局的焦点拦截规则,结合点击状态记录来切换行为,具体步骤如下:
1. 布局初始配置
保留父布局的焦点与点击属性,初始设置descendantFocusability="blocksDescendants"以拦截子项焦点:
<RelativeLayout android:id="@+id/rll" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:focusable="true" android:focusableInTouchMode="true" android:descendantFocusability="blocksDescendants" android:clickable="true"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_benchmarks" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="5dp" android:divider="#ffffff" android:dividerHeight="1dp" android:footerDividersEnabled="true" android:headerDividersEnabled="true" android:scrollbars="vertical" /> </RelativeLayout>
2. 代码逻辑实现
通过点击状态标记,动态修改父布局的焦点拦截规则,并确保首次点击时父布局获取焦点:
Kotlin 示例
private var isFirstClick = true private lateinit var rll: RelativeLayout override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.your_layout_file) rll = findViewById(R.id.rll) rll.setOnClickListener { if (isFirstClick) { // 首次点击:强制父布局获取焦点,确保子项无法抢占 rll.requestFocus() // 修改焦点拦截规则,允许后续子项获取焦点 rll.descendantFocusability = ViewGroup.FOCUS_AFTER_DESCENDANTS // 标记为非首次点击 isFirstClick = false // 此处添加你的展开逻辑(无需关注) } // 第二次及以后点击:子项可正常获取焦点,无需额外拦截 } // 初始加载时让父布局获取焦点(可选,根据需求调整) rll.requestFocus() }
Java 示例
private boolean isFirstClick = true; private RelativeLayout rll; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout_file); rll = findViewById(R.id.rll); rll.setOnClickListener(v -> { if (isFirstClick) { // 首次点击:强制父布局获取焦点 rll.requestFocus(); // 修改焦点拦截规则,允许子项获焦 rll.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); isFirstClick = false; // 展开逻辑(无需关注) } }); // 初始让父布局获焦 rll.requestFocus(); }
关键说明
descendantFocusability="blocksDescendants":初始状态下完全拦截子项的焦点请求,确保父布局能优先获取焦点和点击事件。- 动态切换为
FOCUS_AFTER_DESCENDANTS:第二次点击后,子项可以正常请求焦点,父布局仅在子项未获取焦点时才会获焦。 requestFocus():主动让父布局获取焦点,避免点击时焦点被意外抢占。
内容的提问来源于stack exchange,提问作者Jawegiel
相关产品推荐
相关产品推荐

