Flutter media_kit:如何在视频暂停时始终显示播放按钮或primaryButtonBar?
基于media_kit实现暂停时始终显示播放控件的方案
要在沿用MaterialVideoControlsTheme样式的前提下,实现视频暂停时始终显示播放按钮或primaryButtonBar,可以通过继承默认的MaterialVideoControls并重写可见性控制逻辑来实现,无需完全自定义整套控件:
步骤1:自定义控件类
创建一个继承自MaterialVideoControls的子类,重写控件可见性的判断逻辑,让暂停状态下强制显示关键控件:
import 'package:media_kit_video/media_kit_video.dart'; import 'package:stream_transform/stream_transform.dart'; class PersistentPauseControls extends MaterialVideoControls { const PersistentPauseControls({super.key}); @override Widget _buildControls(BuildContext context, VideoState state) { final player = state.widget.controller.player; final theme = MaterialVideoControlsTheme.of(context); return StreamBuilder( stream: CombineLatestStream.list([ player.stream.playing, player.stream.buffering, _visibilityStream, ]), builder: (context, snapshot) { final data = snapshot.data; final isPlaying = data?[0] ?? false; final isBuffering = data?[1] ?? false; final isUserVisible = data?[2] ?? false; // 核心修改:暂停时强制让控件保持可见 final shouldShowControls = isUserVisible || !isPlaying || isBuffering; return AnimatedOpacity( opacity: shouldShowControls ? 1.0 : 0.0, duration: theme.animationDuration, child: IgnorePointer( ignoring: !shouldShowControls, child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ _buildPrimaryButtonBar(context, state), // 播放/暂停按钮所在的Bar _buildSecondaryButtonBar(context, state), // 进度条、音量等控件Bar ], ), ), ); }, ); } }
如果只需要单独显示播放按钮(而非整个控件栏),可以修改为以下实现:
class PersistentPlayButtonControls extends MaterialVideoControls { const PersistentPlayButtonControls({super.key}); @override Widget build(BuildContext context, VideoState state) { final player = state.widget.controller.player; final defaultControls = super.build(context, state); return StreamBuilder( stream: player.stream.playing, initialData: player.state.playing, builder: (context, snapshot) { final isPlaying = snapshot.data ?? false; // 播放时用默认控件,暂停时叠加显示居中的播放按钮 return Stack( fit: StackFit.expand, children: [ defaultControls, if (!isPlaying) Center( child: IconButton( iconSize: 64, icon: Icon(Icons.play_arrow, color: Colors.white.withOpacity(0.8)), onPressed: () => player.play(), ), ), ], ); }, ); } }
步骤2:使用自定义控件
在Video组件中指定自定义的controls,同时保留MaterialVideoControlsTheme的样式配置:
MaterialVideoControlsTheme( normal: const MaterialVideoControlsThemeData( visibleOnMount: true, // 保留原有的主题配置,比如颜色、动画时长等 ), fullscreen: const MaterialVideoControlsThemeData(), child: Scaffold( body: Video( controller: controller, controls: (state) => const PersistentPauseControls(), // 或者用单独显示播放按钮的版本:const PersistentPlayButtonControls() ), ), );
说明
- 这种方式完全复用了
MaterialVideoControls的原有实现和MaterialVideoControlsTheme的样式配置,只需修改核心的可见性判断逻辑。 - 无需从零实现进度条、音量控制、全屏切换等所有控件功能,减少重复代码。
内容的提问来源于stack exchange,提问作者Fawad Bhatti
相关产品推荐
相关产品推荐

