横屏时结束ActionMode,避免onConfigurationChanged调用finish引发重绘的方案
解决Fragment中横屏时结束ActionMode避免重绘的问题
你当前的实现虽然能生效,但在onConfigurationChanged()中直接调用actionMode.finish()会打断配置变更的UI重绘流程,触发警告。这里有几个更稳妥的方案:
方案1:使用Handler延迟执行finish()
通过Handler.post()将finish()的调用推迟到当前配置变更的UI更新流程完成后执行,避免干扰重绘:
override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Handler(Looper.getMainLooper()).post { actionMode?.finish() } } }
注意加上空安全判断actionMode?.,避免空指针异常。
方案2:标记状态后在生命周期后期处理
在onConfigurationChanged()中记录需要结束ActionMode的状态,然后在onPostResume()中执行结束操作——这个生命周期方法会在配置变更后的UI完全重建并恢复后被调用:
private var needFinishActionMode = false override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) needFinishActionMode = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE } override fun onPostResume() { super.onPostResume() if (needFinishActionMode) { actionMode?.finish() needFinishActionMode = false } }
方案3:使用OrientationEventListener监听方向变化
注册一个OrientationEventListener,在检测到横屏时直接结束ActionMode,这种方式不依赖onConfigurationChanged(),也不会干扰配置变更的流程:
private var orientationListener: OrientationEventListener? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) orientationListener = object : OrientationEventListener(requireContext()) { override fun onOrientationChanged(orientation: Int) { // 过滤掉不确定的方向,只处理明确的横屏状态 val isLandscape = orientation in 90..270 && orientation !in 170..190 if (isLandscape && actionMode != null) { actionMode?.finish() } } } orientationListener?.enable() } override fun onDestroyView() { super.onDestroyView() orientationListener?.disable() }
记得在Fragment销毁时禁用监听器,防止内存泄漏。
内容的提问来源于stack exchange,提问作者user21928976
相关产品推荐
相关产品推荐

