youtube_player_flutter:^8.1.1全屏功能异常问题求助
问题分析与解决方案
核心问题定位
你的代码存在几个关键问题,直接导致全屏播放异常:
- 单一控制器被重复赋值:全局仅声明一个
_youtubePlayerController,但在ListView.builder的每个列表项中都重新赋值该控制器,导致播放器状态混乱,全屏切换时无法正确维护播放会话。 - 生命周期方法拼写错误:
dipose应为dispose,导致控制器无法正确释放,引发内存泄漏和状态异常。 - YoutubePlayerBuilder用法错误:该组件用于包裹单个播放器以处理全屏逻辑,你在全局使用它包裹整个页面,但列表中存在多个播放器,导致全屏逻辑冲突。
修复步骤
1. 为每个列表项创建独立控制器
将列表项封装为独立的StatefulWidget,每个项管理自己的YoutubePlayerController,避免状态冲突。
2. 修正生命周期方法
确保dispose方法拼写正确,在组件销毁时释放控制器资源。
3. 移除全局YoutubePlayerBuilder
每个播放器单独处理全屏逻辑,无需全局包裹。
修改后的代码示例
列表项组件
class YoutubeVideoItem extends StatefulWidget { final String videoLink; final String channelName; final String city; final String username; final String postDateTime; const YoutubeVideoItem({ Key? key, required this.videoLink, required this.channelName, required this.city, required this.username, required this.postDateTime, }) : super(key: key); @override State<YoutubeVideoItem> createState() => _YoutubeVideoItemState(); } class _YoutubeVideoItemState extends State<YoutubeVideoItem> { late YoutubePlayerController _controller; @override void initState() { super.initState(); final videoId = YoutubePlayer.convertUrlToId(widget.videoLink); _controller = YoutubePlayerController( initialVideoId: videoId ?? '', flags: const YoutubePlayerFlags( autoPlay: false, ), ); } @override void deactivate() { _controller.pause(); super.deactivate(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.all(8), child: Card( color: Color(hexColors("03A9F4")), elevation: 6, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), child: Column( children: [ YoutubePlayer( controller: _controller, showVideoProgressIndicator: true, ), Row( children: [ Expanded( child: Padding( padding: const EdgeInsets.only(left: 5.0), child: Text( "Channel Name:- ${widget.channelName}", style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ), ], ), Row( children: [ Expanded( child: Padding( padding: const EdgeInsets.only(left: 5), child: Text( "City : ${widget.city}", style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ), ], ), Padding( padding: const EdgeInsets.all(8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( widget.username, style: const TextStyle(color: Colors.white), ), Text( widget.postDateTime, style: const TextStyle(color: Colors.white), ), ], ), ), ], ), ), ); } int hexColors(String color) => int.parse(color, radix: 16) + 0xFF000000; }
主页面组件
class _LiveProgramState extends State<LiveProgram> { @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( appBar: AppBar( title: const Text( "Live Program", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 25, ), ), centerTitle: true, backgroundColor: Color(hexColors('006064')), ), body: FutureBuilder<LinkModel>( future: getAllLinks(), builder: (context, snapshot) { if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data!.data!.length, itemBuilder: (context, index) { var allItem = snapshot.data!.data![index]; return YoutubeVideoItem( videoLink: allItem.link!, channelName: allItem.channelName!, city: allItem.city!, username: allItem.username.toString(), postDateTime: allItem.postDateTime.toString(), ); }, ); } else if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator(), ); } else if (snapshot.hasError) { return const Center( child: Text("No Data !"), ); } else { return const Center( child: Text("No Data"), ); } }, ), ), ); } int hexColors(String color) => int.parse(color, radix: 16) + 0xFF000000; }
其他错误说明
- "Access denied finding property 'vendor.camera.aux.packagelist'":这是Android系统级警告,与相机辅助属性相关,不影响YouTube播放器功能,可忽略。
- OpenGLRenderer及PlayerBase错误:主要由控制器状态混乱引发,修复控制器复用问题后会自动消失。
内容的提问来源于stack exchange,提问作者Taki Rajani
相关产品推荐
相关产品推荐

