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

如何为Xamarin MediaElement视频播放器添加可用全屏按钮

Xamarin.Forms MediaElement 列表页全屏播放实现方案

当前基础播放实现代码如下:

xmlns:xct="http://xamarin.com/schemas/2020/toolkit"

 <xct:MediaElement Grid.Row="0"
        Aspect="AspectFill"
        HeightRequest="{OnIdiom Phone=170,
                                Tablet=170,
                                Desktop=170}"
        WidthRequest="{OnIdiom Phone=343,
                               Tablet=343,
                               Desktop=423}"
        Source="urllllllllllllllllllll" 
        AutoPlay="True" Background="transparent" IsTabStop="True" ShowsPlaybackControls="True"/>

当前运行效果:
运行效果截图

实现步骤

1. 修改XAML布局

首先将原有播放器和新增的全屏按钮放在同一个Grid容器内(Grid同单元格内容默认叠放,按钮写在播放器后方保证层级更高不被遮挡),同时给页面根布局、播放器、按钮设置命名,方便后台逻辑调用。
完整布局参考代码:

<!-- 页面根布局,用于全屏时挂载播放器 -->
<Grid x:Name="RootGrid">
    <ListView CachingStrategy="RecycleElement" x:Name="VideoList">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="16">
                        <!-- 播放器外层容器 -->
                        <Grid x:Name="PlayerContainer"
                              HorizontalOptions="Center">
                            <xct:MediaElement x:Name="VideoPlayer"
                                              Grid.Row="0"
                                              Aspect="AspectFill"
                                              HeightRequest="{OnIdiom Phone=170,
                                                                      Tablet=170,
                                                                      Desktop=170}"
                                              WidthRequest="{OnIdiom Phone=343,
                                                                     Tablet=343,
                                                                     Desktop=423}"
                                              Source="urllllllllllllllllllll" 
                                              AutoPlay="True" 
                                              Background="transparent" 
                                              IsTabStop="True" 
                                              ShowsPlaybackControls="True"/>
                            <!-- 全屏切换按钮,固定在播放器右上角 -->
                            <ImageButton x:Name="FullScreenToggleBtn"
                                         Grid.Row="0"
                                         Source="fullscreen.png"
                                         HorizontalOptions="End"
                                         VerticalOptions="Start"
                                         Margin="0,10,10,0"
                                         HeightRequest="36"
                                         WidthRequest="36"
                                         CornerRadius="18"
                                         BackgroundColor="#50000000"
                                         Padding="8"
                                         Clicked="FullScreenToggleBtn_Clicked"/>
                        </Grid>
                        <!-- 列表项其他文本/内容区域 -->
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

2. 编写全屏切换后台逻辑

因为播放器嵌在ListView列表项中,直接修改宽高无法突破列表项的布局限制,所以全屏时需要将播放器临时挂载到页面根布局,退出全屏时再放回原容器,同时处理屏幕方向、系统栏显示状态的切换。
首先在页面后台代码中定义状态记录字段:

private bool _isFullScreen = false;
// 记录播放器非全屏状态下的参数,用于退出全屏时还原
private Grid _originalPlayerParent;
private double _originalPlayerHeight;
private double _originalPlayerWidth;
private Aspect _originalPlayerAspect;

然后实现按钮点击事件:

private void FullScreenToggleBtn_Clicked(object sender, EventArgs e)
{
    var btn = (ImageButton)sender;
    if (!_isFullScreen)
    {
        // 进入全屏
        // 记录原始状态
        _originalPlayerParent = (Grid)VideoPlayer.Parent;
        _originalPlayerHeight = VideoPlayer.HeightRequest;
        _originalPlayerWidth = VideoPlayer.WidthRequest;
        _originalPlayerAspect = VideoPlayer.Aspect;

        // 将播放器从列表项容器移到页面根布局
        _originalPlayerParent.Children.Remove(VideoPlayer);
        RootGrid.Children.Add(VideoPlayer);

        // 设置播放器铺满屏幕
        Grid.SetRowSpan(VideoPlayer, 999);
        var screenMetrics = DeviceDisplay.MainDisplayInfo;
        VideoPlayer.HeightRequest = screenMetrics.Height / screenMetrics.Density;
        VideoPlayer.WidthRequest = screenMetrics.Width / screenMetrics.Density;
        VideoPlayer.Aspect = Aspect.AspectFit;
        VideoPlayer.Margin = 0;

        // 隐藏导航栏,切换横屏
        NavigationPage.SetHasNavigationBar(this, false);
        MessagingCenter.Send(this, "ForceLandscape");

        // 切换按钮图标为退出全屏样式
        btn.Source = "exit_fullscreen.png";
        _isFullScreen = true;
    }
    else
    {
        // 退出全屏
        // 将播放器移回原列表容器
        RootGrid.Children.Remove(VideoPlayer);
        _originalPlayerParent.Children.Insert(0, VideoPlayer);

        // 还原播放器参数
        Grid.SetRowSpan(VideoPlayer, 1);
        VideoPlayer.HeightRequest = _originalPlayerHeight;
        VideoPlayer.WidthRequest = _originalPlayerWidth;
        VideoPlayer.Aspect = _originalPlayerAspect;
        VideoPlayer.Margin = 0;

        // 还原导航栏,切换竖屏
        NavigationPage.SetHasNavigationBar(this, true);
        MessagingCenter.Send(this, "ForcePortrait");

        // 切换按钮图标为全屏样式
        btn.Source = "fullscreen.png";
        _isFullScreen = false;
    }
}

3. 添加平台端屏幕方向控制

在各平台项目中注册消息监听,实现强制横竖屏切换:

Android端(MainActivity.cs)

在OnCreate方法中添加以下代码:

MessagingCenter.Subscribe<YourVideoListPage>(this, "ForceLandscape", page =>
{
    RequestedOrientation = ScreenOrientation.Landscape;
    Window.AddFlags(WindowManagerFlags.Fullscreen);
});
MessagingCenter.Subscribe<YourVideoListPage>(this, "ForcePortrait", page =>
{
    RequestedOrientation = ScreenOrientation.Portrait;
    Window.ClearFlags(WindowManagerFlags.Fullscreen);
});

记得将YourVideoListPage替换为你实际的列表页类名。

iOS端(AppDelegate.cs)

在FinishedLaunching方法中添加以下代码:

MessagingCenter.Subscribe<YourVideoListPage>(this, "ForceLandscape", page =>
{
    UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)UIInterfaceOrientation.LandscapeLeft), new NSString("orientation"));
    UIApplication.SharedApplication.StatusBarHidden = true;
});
MessagingCenter.Subscribe<YourVideoListPage>(this, "ForcePortrait", page =>
{
    UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)UIInterfaceOrientation.Portrait), new NSString("orientation"));
    UIApplication.SharedApplication.StatusBarHidden = false;
});

注意事项

  • 代码中用到的fullscreen.png、exit_fullscreen.png需要替换为你项目中实际存放的图标资源
  • 列表的CachingStrategy建议设置为RecycleElement避免列表滚动时播放器实例复用导致的状态异常
  • 重写页面的OnDisappearing方法,在页面离开时判断如果处于全屏状态先执行退出全屏逻辑,避免屏幕方向未还原影响其他页面
  • 如果需要支持安卓返回键退出全屏,可以重写页面的OnBackButtonPressed方法,判断全屏状态时先执行退出逻辑再响应返回

内容的提问来源于stack exchange,提问作者Gazdallah Amira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:03:19