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

Flutter中setState()无法更新Container颜色及播放状态显示问题

解决方案

问题根源

  1. YoutubePlayerController未初始化,导致状态关联异常
  2. selectedIndex的late修饰符使用错误,干扰状态更新机制
  3. 缺少控制器的生命周期管理,可能引发内存泄漏或状态不同步
  4. 点击事件中状态更新与视频加载的顺序可能导致UI未及时刷新

修正后的完整代码

class _VideoDetailState extends State<VideoDetail> {
  late YoutubePlayerController _controller;
  int selectedIndex = 0; // 移除多余的late修饰符
  final links = <String>["Dx2HBxOXccs", "1AM5Fgb-qjA"];

  @override
  void initState() {
    super.initState();
    // 初始化控制器,关联初始视频
    _controller = YoutubePlayerController(
      initialVideoId: links[selectedIndex],
      flags: const YoutubePlayerFlags(
        autoPlay: false,
        mute: false,
      ),
    );
  }

  @override
  void dispose() {
    // 释放控制器资源,避免内存泄漏
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: YoutubePlayerScaffold( // 移除不必要的Stack包裹
        controller: _controller,
        builder: (context, player) {
          return Scaffold(
            body: Column(
              children: [
                player,
                Expanded(
                  child: ListView.builder(
                    itemCount: links.length, // 用数组长度代替硬编码的2
                    itemBuilder: (context, index) {
                      return Column(
                        children: [
                          const SizedBox(height: 5.0),
                          GestureDetector(
                            onTap: () {
                              // 合并状态更新与视频加载逻辑,确保UI及时刷新
                              setState(() {
                                selectedIndex = index;
                              });
                              _controller.loadVideoById(
                                videoId: links[index],
                              );
                            },
                            child: Container(
                              decoration: BoxDecoration(
                                // 先用显眼颜色测试,确认状态生效后再换回ColorConstants
                                color: index == selectedIndex ? Colors.blue : Colors.white,
                              ),
                              child: Padding(
                                padding: const EdgeInsets.all(12.0),
                                child: Row(
                                  children: [
                                    Center(
                                      child: Stack(
                                        children: [
                                          Container(
                                            alignment: Alignment.center,
                                            height: 50,
                                            child: Image.asset(
                                              "images/video.png",
                                              height: 50,
                                            ),
                                          ),
                                          Positioned(
                                            bottom: 15.0,
                                            left: 20.0,
                                            child: Align(
                                              alignment: Alignment.bottomRight,
                                              child: SvgPicture.asset(
                                                  "images/icons/play.svg",
                                                  height: 22.0),
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                    const SizedBox(width: 10),
                                    Column(
                                      mainAxisAlignment: MainAxisAlignment.start,
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        const CustomText(
                                          text: "Basic Introduction of shapes",
                                          fontSize: 14.0,
                                        ),
                                        const SizedBox(height: 5),
                                        IntrinsicHeight(
                                          child: Row(
                                            children: [
                                              const CustomText(
                                                text: "03:40 min",
                                                level: "thin",
                                                fontSize: 13.0,
                                                color: ColorConstants.textColor1,
                                              ),
                                              const SizedBox(width: 1.0),
                                              const SizedBox(
                                                height: 12.0,
                                                child: VerticalDivider(
                                                  thickness: 1.0,
                                                  color: ColorConstants.textColor1,
                                                ),
                                              ),
                                              CustomText(
                                                text: index == selectedIndex
                                                    ? "Now Playing..."
                                                    : "Viewed",
                                                level: "thin",
                                                fontSize: 13.0,
                                                color: index == selectedIndex
                                                    ? ColorConstants.redColor
                                                    : ColorConstants.greenColor,
                                              )
                                            ],
                                          ),
                                        ),
                                      ],
                                    )
                                  ],
                                ),
                              ),
                            ),
                          ),
                        ],
                      );
                    },
                  ),
                )
              ],
            ),
          );
        },
      ),
    );
  }
}

关键修改点说明

  • 控制器初始化:在initState中创建YoutubePlayerController,关联初始视频ID,确保状态正常绑定
  • 移除多余Stack:原代码中YoutubePlayerScaffold外层的Stack无实际作用,移除后避免上下文层级问题
  • 修正selectedIndex声明:去掉late修饰符,直接初始化,确保状态变量正常响应setState
  • 生命周期管理:添加dispose方法释放控制器资源,避免内存泄漏
  • 动态列表长度:用links.length代替硬编码的2,提升代码可维护性
  • 合并更新逻辑:将selectedIndex的状态更新与视频加载放在同一流程,确保UI同步刷新

额外排查建议

  1. 测试时先将选中状态的颜色改为Colors.blue等显眼颜色,确认状态生效后再换回ColorConstants.drawerbgColor
  2. 检查CustomText组件是否正确传递并应用color参数,确保文本颜色变化正常显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:35:25