Xamarin.Forms:如何利用MediaPlayer的isPlaying状态关闭ActivityIndicator?
利用MediaPlayer的
isPlaying状态关闭加载提示的可行方案 嘿,这个需求完全可行!而且用isPlaying状态来判断视频加载完成并关闭ActivityIndicator和标签是个很合理的思路。不过因为Xamarin.Forms是跨平台框架,原生MediaPlayer的状态需要传递到Forms层才能绑定到IsBusy属性,我给你梳理两种具体实现方式:
方法一:自定义视频控件+原生渲染器(适合原生VideoView场景)
如果你的项目用的是原生Android VideoView,需要通过自定义渲染器把原生的播放状态传递到Forms层:
1. 在Forms项目中创建自定义视频控件
先定义一个带播放状态属性和事件的控件,用来接收原生层的状态:
public class CustomVideoPlayer : View { // 定义可绑定的IsPlaying属性 public static readonly BindableProperty IsPlayingProperty = BindableProperty.Create(nameof(IsPlaying), typeof(bool), typeof(CustomVideoPlayer), false); public bool IsPlaying { get => (bool)GetValue(IsPlayingProperty); set => SetValue(IsPlayingProperty, value); } // 定义播放开始的事件 public event EventHandler PlaybackStarted; internal void TriggerPlaybackStarted() { PlaybackStarted?.Invoke(this, EventArgs.Empty); } }
2. 实现Android平台的自定义渲染器
在Android项目中写渲染器,监听原生VideoView的Prepared事件(视频加载完成准备播放时触发),然后同步状态到Forms控件:
[assembly: ExportRenderer(typeof(CustomVideoPlayer), typeof(CustomVideoPlayerRenderer))] namespace YourAppName.Droid.Renderers { public class CustomVideoPlayerRenderer : ViewRenderer<CustomVideoPlayer, Android.Widget.VideoView> { protected override void OnElementChanged(ElementChangedEventArgs<CustomVideoPlayer> e) { base.OnElementChanged(e); if (Control == null) { var nativeVideoView = new Android.Widget.VideoView(Context); SetNativeControl(nativeVideoView); } if (e.NewElement != null) { // 监听视频准备完成事件 Control.Prepared += OnVideoPrepared; // 这里可以设置视频源,比如Control.SetVideoURI(Uri.Parse("你的视频地址")); } if (e.OldElement != null) { // 取消事件订阅避免内存泄漏 Control.Prepared -= OnVideoPrepared; } } private void OnVideoPrepared(object sender, EventArgs e) { Control.Start(); // 启动播放 // 同步状态到Forms控件 Element.IsPlaying = true; Element.TriggerPlaybackStarted(); } } }
3. 在Forms页面中绑定处理
在XAML里使用自定义控件,然后订阅事件来关闭IsBusy:
<StackLayout> <ActivityIndicator IsRunning="{Binding IsBusy}" IsVisible="{Binding IsBusy}" /> <Label Text="视频加载中..." IsVisible="{Binding IsBusy}" /> <local:CustomVideoPlayer x:Name="MyCustomPlayer" /> </StackLayout>
后台代码处理:
public VideoPage() { InitializeComponent(); // 开始加载视频时开启加载提示 this.IsBusy = true; // 订阅播放开始事件 MyCustomPlayer.PlaybackStarted += (s, e) => this.IsBusy = false; // 设置视频源(需要在自定义控件中扩展对应的方法) // MyCustomPlayer.SetVideoSource("你的视频URL"); }
方法二:使用第三方视频库(更快捷)
如果不想自己写渲染器,推荐用成熟的第三方库比如Plugin.MediaManager,它已经封装了播放状态的绑定属性和事件:
- 安装NuGet包
Plugin.MediaManager和对应平台的包 - 在XAML中使用视频控件:
<media:VideoView x:Name="MediaPlayerView" />
- 后台监听播放状态:
public VideoPage() { InitializeComponent(); this.IsBusy = true; // 监听播放状态变化 MediaManager.Current.StateChanged += (s, e) => { if (e.State == MediaManager.Playback.State.Playing) { this.IsBusy = false; } }; // 设置视频源 await MediaManager.Current.Play("你的视频URL"); }
注意事项
- 如果你需要处理视频缓冲的场景(比如加载后中途缓冲),可以额外监听原生VideoView的
BufferingUpdate事件,不过你需求中的“完全加载完成”,用Prepared事件就足够了。 - 记得在页面销毁时取消所有事件订阅,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Tom F
相关产品推荐
相关产品推荐

