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

Android ViewGroup.addView()调用成功但子View不显示如何解决

问题根因

动态添加的TextView不显示和sleep_records_container容器高度无关,核心错误是动态创建控件时的宽高设置方式不对:

  • 你直接调用startSleepTextView.width = LayoutParams.WRAP_CONTENT、startSleepTextView.height = LayoutParams.WRAP_CONTENT是无效写法。View类的width/height属性只接收实际像素尺寸值,而LayoutParams.WRAP_CONTENT的常量值为-2,直接赋值相当于把控件宽高设为-2px,控件测量后实际尺寸为0,自然无法渲染显示。
  • 所有布局规则类参数(包括WRAP_CONTENT、MATCH_PARENT、边距、对齐规则等),必须通过控件的LayoutParams对象设置,不能直接赋值给View的宽高属性。
  • 额外隐患:你创建的内层包裹用sleepRecordLinearLayout也没有设置合法的布局参数,同时观察LiveData时用this作为生命周期宿主,在Fragment销毁视图时会有内存泄漏风险。
修复方案

将观察oneMonthSleepRecords的代码替换为如下正确实现即可:

// 注意这里把this替换成viewLifecycleOwner,适配Fragment视图生命周期
sleepRecordViewModel.oneMonthSleepRecords.observe(viewLifecycleOwner, Observer { oneMonthSleepRecords ->
    Log.i("SleepRecordFragment", "oneMonthSleepRecords.size: ${oneMonthSleepRecords.size}")

    binding.sleepRecordsContainer.removeAllViews()
    oneMonthSleepRecords.forEach { sleepRecord ->
        Log.i("SleepRecordFragment", "Observe oneMonthSleepRecords: ${sleepRecord.toString()}")

        // 创建TextView,通过LayoutParams设置宽高规则
        val startSleepTextView = TextView(requireContext()).apply {
            val startSleepDate = Date(sleepRecord.startTimeMilli)
            // 显式传入Locale,避免区域设置导致的日期格式异常
            val formatter = SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault())
            val startSleepText = getString(R.string.start_sleep_datetime, formatter.format(startSleepDate))
            text = startSleepText
            // 注意:LayoutParams的类型要和父容器类型匹配,父容器是LinearLayout就用LinearLayout.LayoutParams
            layoutParams = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            )
            Log.i("SleepRecordFragment", "start sleep text: ${startSleepText}")
        }

        // 创建内层包裹的垂直线性布局,同样设置合法LayoutParams
        val sleepRecordLinearLayout = LinearLayout(requireContext()).apply {
            orientation = LinearLayout.VERTICAL
            layoutParams = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            )
            addView(startSleepTextView)
        }

        binding.sleepRecordsContainer.addView(sleepRecordLinearLayout)
    }

    Log.i("SleepRecordFragment", "size in sleep record container: ${binding.sleepRecordsContainer.size}")
})

修改后重新运行即可看到动态添加的睡眠记录文本,不需要修改现有XML布局的容器高度配置。

内容的提问来源于stack exchange,提问作者リョウタ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:39:15