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

.NET MAUI垂直滑动列表(类TikTok):可见项MediaElement自动播放问题

.NET MAUI 实现滚动列表自动播放可见视频(TikTok/Reels 风格)

核心思路

通过监听列表的可见项变化,仅让当前处于屏幕主要可见区域的视频自动播放,同时暂停其他不可见视频,核心依赖原生CollectionView的滚动与可见项监听能力。

具体实现步骤

  1. 选用原生CollectionView控件
    放弃第三方控件,改用.NET MAUI原生CollectionView,它原生支持VisibleItemsChanged事件,能直接获取滚动过程中可见的项集合,适配性和稳定性更有保障。

  2. 配置列表布局
    将列表设置为垂直全屏项布局,确保每个视频项占满屏幕,方便准确判断可见性:

    <CollectionView ItemsSource="{Binding VideoList}"
                    VisibleItemsChanged="CollectionView_VisibleItemsChanged">
        <CollectionView.ItemsLayout>
            <LinearItemsLayout Orientation="Vertical"
                               ItemSpacing="0"
                               ItemSizingStrategy="MeasureFirstItem"/>
        </CollectionView.ItemsLayout>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <MediaElement Source="{Binding VideoSource}"
                                  IsPlaying="{Binding IsAutoPlaying}"
                                  Aspect="AspectFill"
                                  HorizontalOptions="Fill"
                                  VerticalOptions="Fill"/>
                    <!-- 可添加视频标题、点赞等其他元素 -->
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    
  3. 监听可见项变化并控制播放
    在后台代码中处理VisibleItemsChanged事件,暂停之前可见的视频,播放当前最优先的可见视频(通常是第一个完全可见项):

    private async void CollectionView_VisibleItemsChanged(object sender, ItemsViewVisibleItemsChangedEventArgs e)
    {
        // 暂停所有之前可见的视频
        foreach (var prevItem in e.PreviousVisibleItems)
        {
            if (prevItem is VideoItemViewModel prevVm)
            {
                prevVm.IsAutoPlaying = false;
            }
        }
    
        // 延迟300ms,避免滚动过程中频繁触发播放
        await Task.Delay(300);
    
        // 获取当前可见项中的第一个,设置自动播放
        if (e.VisibleItems.FirstOrDefault() is VideoItemViewModel currentVm)
        {
            currentVm.IsAutoPlaying = true;
        }
    }
    
  4. ViewModel绑定属性
    给视频项的ViewModel添加IsAutoPlaying属性,实现INotifyPropertyChanged以绑定到MediaElement:

    public class VideoItemViewModel : INotifyPropertyChanged
    {
        private bool _isAutoPlaying;
        public bool IsAutoPlaying
        {
            get => _isAutoPlaying;
            set
            {
                _isAutoPlaying = value;
                OnPropertyChanged(nameof(IsAutoPlaying));
            }
        }
    
        public string VideoSource { get; set; } // 存储通过Youtube API获取的视频播放地址
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

进阶优化点

  • 精准判断可见区域:如果需要更精确的可见性判断(比如仅播放占据屏幕80%以上的项),可以通过VisualTreeHelper获取列表项的布局位置,计算与屏幕的重叠比例。
  • 平台适配:
    • iOS:需要在Info.plist中添加后台播放权限,避免切后台暂停。
    • Android:处理媒体焦点,防止其他应用抢占音频。
  • 性能优化:利用CollectionView的虚拟化特性,避免一次性加载所有视频,同时在视频不可见时释放媒体资源。
  • 错误处理:监听MediaElement的MediaFailed事件,处理视频加载失败的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 00:27:05