如何实现类似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
相关产品推荐
相关产品推荐

