Android手机中Compose DialogFragment重复渲染问题求助
问题:Jetpack Compose Popover在手机端出现视图残留、阴影加深及内存增长问题
我们的遗留项目基于1.0.0 AppCompatActivity,计划在新功能中使用Jetpack Compose实现一个悬浮于Activity内容上方、非全屏且带阴影的popover组件。为此采用全屏DialogFragment嵌入ComposeView的方案,核心代码如下:
class MyDialogFragment : AppCompatDialogFragment() { private val dismiss: () -> Unit = { this.dismiss() } private lateinit var tapPoint: Point fun initialize(tapPoint: Point) { this.tapPoint = tapPoint } @OptIn(ExperimentalPagerApi::class) override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setViewCompositionStrategy(DisposeOnViewTreeLifecycleDestroyed) setContent { MyDialogScreen( dismiss = dismiss ) } } } fun show(manager: FragmentManager) { super.show(manager, TAG) // the style only makes sure the fragment is displayed full-screen // <style name="MyDialogStyle"> // <item name="android:layout_width">match_parent</item> // <item name="android:layout_height">wrap_content</item> // <item name="android:windowSoftInputMode">adjustResize</item> // </style> this.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.MyDialogStyle) } override fun onStart() { super.onStart() // This makes sure the full-screen dialog has a transparent background, so that the activity content could be seen behind the popover. dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) } companion object { const val TAG: String = "My Dialog" fun newInstance(tapPoint: Point): NotepadDialogFragment { return NotepadDialogFragment() } } }
简化后的Composable代码如下:
@Composable fun MyDialogScreen( dismiss: () -> Unit, tapPoint: Point ) { val windowInfo = rememberWindowInfo() MyTheme( windowInfo = windowInfo, ) { Column(modifier = Modifier.fillMaxSize()) { if (shouldPinToBottom(windowInfo = windowInfo, tapPoint = tapPoint)) { Spacer(modifier = Modifier.weight(1f)) } Column( modifier = Modifier .align(Alignment.CenterHorizontally) .width(width = LocalCustomShape.current.width) .height(height = LocalCustomShape.current.height) .aspectRatio( ratio = LocalCustomShape.current.width / LocalCustomShape.current.height, matchHeightConstraintsFirst = true ) .padding(LocalCustomShape.current.padding) .drawColoredShadow( color = LocalCustomColors.current.shadowColor, shadowRadius = LocalCustomShape.current.shadowRadius, cornerRadius = LocalCustomShape.current.cornerRadius ) ) { MyDialogContent() } } } } @Composable fun MyDialogContent() { Column( modifier = Modifier .fillMaxSize() .background(Color.White) .clip(RoundedCornerShape(LocalCustomShape.current.cornerRadius))){ BasicTextField( value = "Hello world", onValueChange = {}, modifier = Modifier .background(LocalCustomColors.current.textEditorBackground) .fillMaxWidth() .fillMaxHeight() .padding(all = 16.dp), textStyle = LocalCustomTypography.current.textEditor, ) } } private fun shouldPinToBottom(windowInfo: MyWindowInfo, tapPoint: Point): Boolean { return windowInfo.screenWidthInfo != MyWindowInfo.WindowType.Compact && windowInfo.screenHeightInfo != MyWindowInfo.WindowType.Compact && tapPoint.y < windowInfo.screenHeight * HEIGHT_RATIO }
异常现象
- Android 9/11平板运行正常,但Android 9/12手机上出现问题:每次触摸文本编辑框,对话框阴影逐渐加深;键盘弹出导致popover尺寸变化时,旧视图残留于界面。
- 模拟器中问题更严重,甚至出现十余个重复popover、Activity倒置的情况。
已做排查
- App Inspector中始终仅显示一个Composable组件,重组检测结果正常。
- 尝试Compose版本1.0.0至1.2.0 beta,均未解决问题。
- 内存分析显示手机端内存持续增长,平板端则保持稳定。
恳请同行帮忙分析问题原因并提供解决方案。
内容的提问来源于stack exchange,提问作者user7907830
相关产品推荐
相关产品推荐

