Android/Kotlin 点击导航菜单按钮使TextField失焦后Fragment未绑定Activity问题
Android Fragment 切换时避免触发 TextView 焦点监听的解决方案
方案1:新增生命周期状态标记位拦截无效监听
在Fragment内新增布尔类型的生命周期标记,在View销毁时标记为失效,焦点监听回调中先判断标记位再执行业务逻辑:
// Fragment 内定义成员变量 private boolean isFragmentActive = false; @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); isFragmentActive = true; // 给每个可编辑TextView设置监听器 for (TextView editableTv : editableTvList) { editableTv.setOnFocusChangeListener((v, hasFocus) -> { // 仅Fragment存活且为失焦事件时才执行业务逻辑 if (!isFragmentActive || hasFocus) { return; } // 原有服务端API调用逻辑 }); } } @Override public void onDestroyView() { isFragmentActive = false; super.onDestroyView(); }
方案2:切换Fragment前主动移除焦点监听
在菜单按钮的点击逻辑中,执行Fragment切换操作前,先清空当前Fragment所有可编辑TextView的焦点监听器:
// 菜单切换逻辑 private void navigateToMenuFragment(Fragment targetFragment) { Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); if (currentFragment instanceof EditableListFragment) { EditableListFragment listFragment = (EditableListFragment) currentFragment; // 移除所有TextView的焦点监听 for (TextView tv : listFragment.getEditableTvList()) { tv.setOnFocusChangeListener(null); } } // 执行Fragment替换逻辑 getSupportFragmentManager() .beginTransaction() .replace(R.id.fragment_container, targetFragment) .commit(); }
方案3:添加Fragment附着状态判断兜底防崩溃
在焦点监听的API调用前增加isAdded()判断,避免Fragment已脱离Activity时执行业务逻辑抛出异常:
editableTv.setOnFocusChangeListener((v, hasFocus) -> { // 兜底判断:Fragment未附着在Activity上时直接返回 if (!isAdded() || hasFocus) { return; } // API调用逻辑 });
推荐组合使用方案1和方案3,既可以拦截切换页面时的无效监听执行,也能兜底覆盖其他异常场景避免崩溃。
内容的提问来源于stack exchange,提问作者Ivan Vetrugno
相关产品推荐
相关产品推荐

