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

如何让Android应用中ExoPlayer控制器的显示实现平滑淡入效果?

实现ExoPlayer控制器平滑淡入淡出效果

我之前也碰到过这个问题,默认的PlayerControlView显示/隐藏时确实有点生硬,下面是我实践过的两种可行方案,你可以根据自己的需求选:

方案一:自定义PlayerControlView,重写显示/隐藏方法

ExoPlayer的PlayerControlView本身提供了show()和hide()方法,我们可以继承它,在这两个方法里加入淡入淡出动画,替代直接调用setVisibility的生硬逻辑。

步骤1:创建自定义控制器类

class FadingPlayerControlView(context: Context, attrs: AttributeSet?) : PlayerControlView(context, attrs) {

    private val fadeInAnim by lazy {
        AlphaAnimation(0f, 1f).apply {
            duration = 300 // 动画时长,可根据需求调整,比如改成200或400ms
            fillAfter = true
        }
    }

    private val fadeOutAnim by lazy {
        AlphaAnimation(1f, 0f).apply {
            duration = 300
            fillAfter = true
            setAnimationListener(object : Animation.AnimationListener {
                override fun onAnimationStart(animation: Animation?) {}
                override fun onAnimationEnd(animation: Animation?) {
                    // 动画结束后再真正隐藏,避免中间出现突兀的空白
                    super@FadingPlayerControlView.hide()
                }
                override fun onAnimationRepeat(animation: Animation?) {}
            })
        }
    }

    override fun show() {
        // 如果当前正在执行隐藏动画,先取消掉
        clearAnimation()
        visibility = View.VISIBLE
        startAnimation(fadeInAnim)
    }

    override fun hide() {
        // 如果已经不可见,直接返回,避免重复执行
        if (visibility != View.VISIBLE) return
        clearAnimation()
        startAnimation(fadeOutAnim)
    }
}

步骤2:在布局中使用自定义控制器

把原来布局里的com.google.android.exoplayer2.ui.PlayerControlView替换成你自定义的类,比如:

<your.package.name.FadingPlayerControlView
    android:id="@+id/player_control_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    app:show_timeout="3000" /> <!-- 自动隐藏的超时时间,按需设置 -->

方案二:通过监听控制器可见性变化添加动画

如果你不想自定义类,也可以给默认的PlayerControlView添加可见性监听器,在状态变化时触发动画:

代码示例(Kotlin)

val playerControlView = findViewById<PlayerControlView>(R.id.player_control_view)

playerControlView.setOnVisibilityChangeListener { isVisible ->
    val anim = if (isVisible) {
        AlphaAnimation(0f, 1f).apply { duration = 300; fillAfter = true }
    } else {
        AlphaAnimation(1f, 0f).apply { duration = 300; fillAfter = true }
    }
    playerControlView.startAnimation(anim)
}

注意:这种方式需要确保ExoPlayer不会直接跳过动画调用setVisibility,所以如果遇到动画不生效的情况,可以配合setControllerVisibilityListener再做一层判断。

额外优化小技巧

  • 可以调整动画时长,找到最贴合你App风格的速度
  • 如果需要更丰富的效果(比如淡入同时从底部滑入),可以用ObjectAnimator组合动画:
// 淡入+上滑的组合动画
val fadeIn = ObjectAnimator.ofFloat(this, "alpha", 0f, 1f)
val slideUp = ObjectAnimator.ofFloat(this, "translationY", height.toFloat(), 0f)
AnimatorSet().apply {
    playTogether(fadeIn, slideUp)
    duration = 300
    start()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:10:01