Android ExoPlayer自定义控制器DefaultTimeBar无进度无拖动头问题求助
问题原因分析
核心原因:自定义控制器控件ID和ExoPlayer要求的标准ID不匹配
PlayerView内置的控制逻辑是通过固定ID查找控制器子控件的,你当前布局中所有控制相关控件的ID都是自定义的,ExoPlayer无法识别到你的DefaultTimeBar、播放按钮、时间文本控件,自然不会主动更新进度条的播放状态、已播放区域颜色,也不会渲染拖动滑块。
次要可能原因
- DefaultTimeBar缺少滑块相关配置,导致滑块默认透明或尺寸为0无法显示
- ExoPlayer依赖库版本不一致,导致控件渲染异常
- 自定义代码中覆盖了进度更新逻辑,导致进度条无法被正常刷新
修复步骤
1. 替换布局控件为ExoPlayer标准ID
修改你的custom_controller.xml中对应控件的ID,注意使用@id而非@+id引用ExoPlayer库预定义的ID:
- 播放按钮ImageView ID改为
@id/exo_play - 当前播放时间TextView ID改为
@id/exo_position - 总时长TextView ID改为
@id/exo_duration - DefaultTimeBar ID改为
@id/exo_progress
2. 补充DefaultTimeBar缺失的配置属性
修改DefaultTimeBar的配置,确保滑块和进度条可正常显示:
<com.google.android.exoplayer2.ui.DefaultTimeBar android:id="@id/exo_progress" android:layout_gravity="center" android:layout_weight="4" android:layout_width="0dp" <!-- 固定高度避免wrap_content导致的尺寸过小 --> android:layout_height="48dp" android:minHeight="4dp" android:maxHeight="4dp" app:buffered_color="@color/white" app:played_color="@color/red" app:unplayed_color="@color/blue" <!-- 显式配置滑块属性 --> app:scrubber_drawable="@drawable/exo_styled_scrubber" app:scrubber_enabled="true" app:scrubber_size="24dp" <!-- 增大触摸区域方便拖动 --> app:touch_target_height="32dp"/>
3. 验证依赖版本
检查build.gradle中所有ExoPlayer相关依赖的版本号完全一致,避免版本不兼容导致的渲染异常:
def exoplayer_version = "2.18.7" // 可替换为你使用的稳定版本 implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version" implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayer_version"
4. 手动绑定进度更新(可选)
如果修改ID后进度还是没有自动更新,可以在业务代码中手动绑定播放器和时间条的监听:
// Kotlin示例 val playerView = findViewById<PlayerView>(R.id.todayVideo) val player = ExoPlayer.Builder(context).build() playerView.player = player val timeBar = playerView.findViewById<DefaultTimeBar>(R.id.exo_progress) player.addListener(object : Player.Listener { override fun onPlaybackStateChanged(playbackState: Int) { timeBar.setDuration(player.duration) } override fun onPositionDiscontinuity( oldPosition: Player.PositionInfo, newPosition: Player.PositionInfo, reason: Int ) { timeBar.setPosition(player.currentPosition) timeBar.setBufferedPosition(player.bufferedPosition) } override fun onBufferedPositionUpdate(bufferedPosition: Long) { timeBar.setBufferedPosition(bufferedPosition) } }) // 配置拖动进度逻辑 timeBar.addListener(object : DefaultTimeBar.OnScrubListener { override fun onScrubStart(timeBar: DefaultTimeBar, position: Long) { player.pause() } override fun onScrubMove(timeBar: DefaultTimeBar, position: Long) {} override fun onScrubStop(timeBar: DefaultTimeBar, position: Long, canceled: Boolean) { if (!canceled) { player.seekTo(position) } player.play() } })
内容的提问来源于stack exchange,提问作者Sudeep
相关产品推荐
相关产品推荐

