You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

返回Fragment时AbstractComposeView自定义Compose视图不绘制

问题场景

在Fragment的XML布局中使用继承自AbstractComposeView的自定义Compose视图,该Fragment属于Jetpack Navigation导航图的管理范围。

问题现象

首次打开该Fragment时,Compose视图可以正常绘制显示,但按下返回键回到该Fragment时,Compose视图直接消失,仅首次进入时可正常渲染。

相关实现代码
class ProgressComposeView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AbstractComposeView(context, attrs, defStyleAttr) {

    private var steps = mutableStateOf(0)
    private var currentStep: Int = 0
    private var windowWidth: Int = 0

    @Composable
    override fun Content() {
        ProgressView(steps.value, currentStep, windowWidth)
    }

    fun setData(steps: Int, currentStep: Int, windowWidth: Int) {
        this.steps.value = steps
        this.currentStep = currentStep
        this.windowWidth = windowWidth
    }

}


@Composable
fun ProgressView(totalSteps: Int, currentStep: Int, windowWidth: Int) {
// 具体业务布局逻辑
}
问题根因
  • AbstractComposeView默认会在视图从窗口分离(对应Fragment被压入返回栈、视图销毁的场景)时自动释放持有的Compose Composition实例,但在视图重新附着回窗口(对应从返回栈回到该Fragment的场景)时,不会自动重建Composition,导致视图没有可渲染的内容,直接显示空白。
  • 代码中currentStep、windowWidth两个字段是普通基础类型,不属于Compose可观察状态,后续调用setData更新这两个值时,无法触发Compose重组,就算视图正常显示也不会同步最新数据。
修复方案
  1. 修改自定义ProgressComposeView的实现,补全视图重附着时的Composition重建逻辑,同时将所有驱动UI的字段改为Compose可观察状态:
class ProgressComposeView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AbstractComposeView(context, attrs, defStyleAttr) {

    // 所有参与UI渲染的字段都声明为可观察的MutableState
    private var steps by mutableStateOf(0)
    private var currentStep by mutableStateOf(0)
    private var windowWidth by mutableStateOf(0)

    @Composable
    override fun Content() {
        ProgressView(steps, currentStep, windowWidth)
    }

    fun setData(steps: Int, currentStep: Int, windowWidth: Int) {
        this.steps = steps
        this.currentStep = currentStep
        this.windowWidth = windowWidth
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        // 视图重新附着时,若Composition已被释放则主动重建
        if (composition == null) {
            createComposition()
        }
    }
}
  1. 在宿主Fragment的onDestroyView生命周期中,主动调用该Compose视图的disposeComposition()方法释放资源,避免内存泄漏:
override fun onDestroyView() {
    binding.progressComposeView.disposeComposition()
    super.onDestroyView()
}

注意:不要直接将disposeCompositionWhenDetachedFromWindow属性设为false关闭自动释放逻辑,该配置会导致RecyclerView复用、临时视图detach等场景下Compose持有无效引用,提升内存泄漏风险。

内容的提问来源于stack exchange,提问作者Oussaki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:36:20