Android Activity中如何检测所有视图失焦(getCurrentFocus返回null)的事件
实现全局无焦点状态监听的两种可行方案
方案1:OnGlobalFocusChangeListener(全API版本兼容)
在Activity根视图注册全局焦点变化监听,仅需注册一次即可全局生效,无需修改原有业务逻辑:
// Activity onCreate 中添加初始化逻辑 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 原有初始化代码省略 View rootView = getWindow().getDecorView(); rootView.getViewTreeObserver().addOnGlobalFocusChangeListener((oldFocus, newFocus) -> { // newFocus为null时代表当前页面无任何持有焦点的视图 if (newFocus == null) { // 执行你需要的业务逻辑 doOnAllFocusLost(); } }); }
Kotlin写法参考:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 原有初始化代码省略 window.decorView.viewTreeObserver.addOnGlobalFocusChangeListener { _, newFocus -> if (newFocus == null) { doOnAllFocusLost() } } }
注意:如果需要避免内存泄漏,可在Activity
onDestroy生命周期中调用removeOnGlobalFocusChangeListener移除监听。
方案2:重写系统回调(API 29+)
若应用最小支持版本为API 29及以上,可直接重写Activity原生提供的焦点变化回调,性能更稳定:
@Override public void onCurrentFocusChanged(@Nullable View focus) { super.onCurrentFocusChanged(focus); if (focus == null) { doOnAllFocusLost(); } }
GLSurfaceView无法自动获取焦点的修复方案
你遇到的clearFocus后焦点未转移到GLSurfaceView的问题,是因为默认情况下GLSurfaceView未开启触摸模式下的可聚焦属性,添加以下配置即可:
XML配置:
<android.opengl.GLSurfaceView android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="true" android:focusableInTouchMode="true" />
代码动态配置:
glSurfaceView.setFocusable(true); glSurfaceView.setFocusableInTouchMode(true);
若配置后仍存在自动分配焦点失败的情况,可在上述的doOnAllFocusLost方法中主动调用glSurfaceView.requestFocus()进行兜底。
内容的提问来源于stack exchange,提问作者O'Rooney
相关产品推荐
相关产品推荐

