Flutter中setState()无法更新Container颜色及播放状态显示问题
解决方案
问题根源
YoutubePlayerController未初始化,导致状态关联异常selectedIndex的late修饰符使用错误,干扰状态更新机制- 缺少控制器的生命周期管理,可能引发内存泄漏或状态不同步
- 点击事件中状态更新与视频加载的顺序可能导致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同步刷新
额外排查建议
- 测试时先将选中状态的颜色改为
Colors.blue等显眼颜色,确认状态生效后再换回ColorConstants.drawerbgColor - 检查
CustomText组件是否正确传递并应用color参数,确保文本颜色变化正常显示
内容的提问来源于stack exchange,提问作者Manish Tiwari
相关产品推荐
相关产品推荐

