Android返回上一级Fragment时onCreateView自动触发Button onClick如何解决
问题原因与解决方案
核心触发原因
该问题本质是Fragment回退时View重建导致的触摸事件透传:当你从Fragment B调用popBackStackImmediate()回退到A时,A的View因为之前replace操作被销毁后重建,如果你在B页面点击返回按钮的位置刚好和A页面doSomethingBtn的位置重合,系统会把返回操作的ACTION_UP触摸事件分发给刚创建完成的按钮,从而触发点击回调。
可行解决方法
- 方案1:给按钮添加点击延迟判断,避免短时间内的意外触发
在点击回调里加入时间戳判断,过滤掉页面创建后短时间内的异常点击事件:// 类内定义全局变量记录上次点击时间 private long lastClickTime = 0; // onCreateView里设置监听时修改逻辑 doSomethingBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { long currentTime = System.currentTimeMillis(); // 过滤300ms内的重复/意外点击,可自行调整间隔 if (currentTime - lastClickTime < 300) { return; } lastClickTime = currentTime; // 原有点击逻辑写在这里 } }); - 方案2:Fragment A使用hide/show代替replace加载,避免View重建
跳转Fragment B的时候不调用replace,改为隐藏A、添加B的方式,回退后A的View不会重新走onCreateView,也就不会重复设置监听、不会出现事件透传:// 跳转B的代码修改为: B nextFrag = new B(); nextFrag.setArguments(bundleobj); FragmentTransaction transaction = getFragmentManager().beginTransaction(); // 隐藏当前的Fragment A transaction.hide(this); // 添加Fragment B transaction.add(R.id.nav_host_fragment, nextFrag); transaction.addToBackStack(null); transaction.commit(); - 方案3:给按钮设置焦点属性,避免页面刚创建时按钮自动获取焦点触发点击
可以在布局文件里给按钮添加属性:
也可以在代码里设置:<Button android:id="@+id/doSomethingBtn" android:focusable="false" android:focusableInTouchMode="false" ...其他属性/>doSomethingBtn.setFocusable(false); doSomethingBtn.setFocusableInTouchMode(false);
注意:你提供的点击监听代码里
doSomethingBtn..setOnClickListener存在多写一个.的笔误,实际开发时需要修正为doSomethingBtn.setOnClickListener,否则会编译报错。
内容的提问来源于stack exchange,提问作者Josef
相关产品推荐
相关产品推荐

