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

如何实现类似TikTok、Instagram Reels的ViewPager2播放Firebase视频功能?

解决ViewPager2切换视频缓冲问题(仿TikTok/Reels流畅效果)

要实现短视频平台那种滑页即播、无明显缓冲的效果,核心要抓这几个关键点:

1. 开启ViewPager2预加载

ViewPager2默认只预加载1个相邻页面,你可以适当提高预加载数量(比如设为2),让即将滑到的页面提前加载视频资源,避免切换时才开始缓冲:

viewPager2.offscreenPageLimit = 2

注意别设太大,不然会占太多内存导致卡顿。

2. 换掉VideoView,用ExoPlayer

VideoView的缓存和播放控制能力太弱,换成ExoPlayer才能实现缓存、预加载这些功能。配合缓存配置,把视频片段存在本地,切换时直接读缓存:

// 配置100MB本地缓存
val cacheSize = 100 * 1024 * 1024
val cacheDir = File(context.cacheDir, "short_video_cache")
val cache = SimpleCache(cacheDir, LeastRecentlyUsedCacheEvictor(cacheSize.toLong()))

// 构建带缓存的数据源
val dataSourceFactory = DefaultDataSource.Factory(context, DefaultHttpDataSource.Factory())
val cacheDataSourceFactory = CacheDataSource.Factory()
    .setCache(cache)
    .setUpstreamDataSourceFactory(dataSourceFactory)
    .setCacheWriteDataSinkFactory(null) // 只缓存已播放的片段

// 创建ExoPlayer实例
val player = ExoPlayer.Builder(context)
    .setMediaSourceFactory(DefaultMediaSourceFactory(cacheDataSourceFactory))
    .build()

3. 精准控制播放状态

滑页时只让当前页面的视频播放,其他页面暂停并释放资源,避免后台占用带宽和内存:

  • 给ViewPager2加页面选中监听:
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
    override fun onPageSelected(position: Int) {
        super.onPageSelected(position)
        // 暂停所有其他页面的视频
        videoAdapter.pauseAllPlayers()
        // 播放当前页面的视频
        videoAdapter.playPlayerAt(position)
    }
})
  • 在Adapter的ViewHolder里封装播放控制方法:
class VideoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    private val playerView = itemView.findViewById<PlayerView>(R.id.player_view)
    private val exoPlayer = ExoPlayer.Builder(itemView.context).build().apply {
        playerView.player = this
        repeatMode = Player.REPEAT_MODE_ONE // 循环播放,仿短视频逻辑
    }

    fun bind(videoUrl: String) {
        val mediaItem = MediaItem.fromUri(videoUrl)
        exoPlayer.setMediaItem(mediaItem)
        exoPlayer.prepare()
    }

    fun play() = exoPlayer.play()

    fun pause() = exoPlayer.pause()

    fun release() = exoPlayer.release()
}

4. 去掉多余动画,让切换更丝滑

ViewPager2默认的页面切换动画会增加视觉延迟,直接禁用:

viewPager2.setPageTransformer(null)

5. 复用资源,避免重复加载

在Adapter里缓存已创建的Player实例或者MediaItem,不要每次绑定ViewHolder都重新创建Player,减少初始化开销(记得在页面销毁时及时释放Player,防止内存泄漏)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:27:11