如何保存SeekBar数组的位置与可见性?解决Activity切换后SeekBar消失问题
解决ExoPlayer多音频播放返回Activity后SeekBar消失的问题
我使用ExoPlayer同时播放多个音频,每个音频分配了独立的音效控制。但切换到其他Activity再返回后,SeekBar就消失了——此时音频仍在正常播放,只是SeekBar无法显示。
相关代码片段
按钮点击逻辑
play_rain.setOnClickListener { playerService?.toggleSound(PlayerService.Sound.RAIN) toggleProgressBar(rain_volume) }
切换SeekBar显示状态的方法
private fun toggleProgressBar(progressBar: ProgressBar) { progressBar.visibility = if (progressBar.visibility == View.VISIBLE) View.INVISIBLE else View.VISIBLE }
Activity生命周期与服务绑定代码
override fun onStart() { super.onStart() val playerIntent = Intent(this, PlayerService::class.java) startService(playerIntent) bindService(playerIntent, serviceConnection, Context.BIND_AUTO_CREATE) } override fun onStop() { unbindService(serviceConnection) super.onStop() } override fun onResume() { super.onResume() playerService?.stopForeground() } override fun onPause() { playerService?.startForeground() super.onPause() }
FloatingActionButton点击逻辑
fab.setOnClickListener { playerService?.stopPlaying() fab.hide() // 隐藏所有音量条 arrayOf(rain_volume, storm_volume, water_volume, fire_volume, wind_volume, night_volume, cat_volume).forEach { bar -> bar.visibility = View.INVISIBLE } }
问题原因与修复方案
问题核心是Activity恢复时,没有同步后台服务中正在播放的音频状态到UI。切换Activity再返回时,Activity会重建或经历onStop→onStart→onResume周期,虽然重新绑定了服务,但未根据服务内的活跃音频状态恢复对应的SeekBar显示。
具体修复步骤:
- 在PlayerService中维护活跃音频状态:添加集合记录当前正在播放的音频
- Activity绑定服务后同步UI:在
onServiceConnected回调中,根据服务返回的活跃音频列表,恢复对应SeekBar的显示状态
示例修改代码:
- 先给PlayerService添加状态维护方法:
// 记录当前活跃的音频集合 private val activeSounds = mutableSetOf<Sound>() fun toggleSound(sound: Sound) { if (activeSounds.contains(sound)) { // 停止该音频的逻辑 activeSounds.remove(sound) } else { // 播放该音频的逻辑 activeSounds.add(sound) } } // 对外暴露获取活跃音频的方法 fun getActiveSounds(): Set<Sound> = activeSounds.toSet() // 停止所有播放时清空集合 fun stopPlaying() { // 原有停止逻辑 activeSounds.clear() }
- 然后在Activity的服务绑定回调中同步UI:
private val serviceConnection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { val binder = service as PlayerService.LocalBinder playerService = binder.getService() // 同步活跃音频对应的SeekBar显示 playerService?.getActiveSounds()?.forEach { sound -> when(sound) { PlayerService.Sound.RAIN -> rain_volume.visibility = View.VISIBLE PlayerService.Sound.STORM -> storm_volume.visibility = View.VISIBLE PlayerService.Sound.WATER -> water_volume.visibility = View.VISIBLE // 其他音频类型依次对应 } } } override fun onServiceDisconnected(arg0: ComponentName) { playerService = null } }
内容的提问来源于stack exchange,提问作者Sidharth
相关产品推荐
相关产品推荐

