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

Android中如何调整BottomSheetBehaviour(持久化底部弹窗)的动画速度?

调整Android BottomSheetBehavior动画速度的方法

我之前也碰到过BottomSheet动画过快的问题,尤其是从STATE_HIDDEN到STATE_EXPANDED的过渡,下面两种方案可以帮你自定义动画速度:

方案一:重写BottomSheetBehavior自定义动画(推荐)

这种方法最可靠,通过继承BottomSheetBehavior并重写动画创建逻辑,完全掌控动画时长和过渡效果。

步骤1:创建自定义BottomSheetBehavior类

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.animation.Animator
import android.animation.ValueAnimator
import com.google.android.material.bottomsheet.BottomSheetBehavior

class SlowBottomSheetBehavior<V : View>(context: Context, attrs: AttributeSet?) : BottomSheetBehavior<V>(context, attrs) {

    // 自定义动画时长,这里设为2000毫秒(可根据需求调整)
    private val customDuration = 2000L

    override fun createAnimation(
        view: V,
        start: Float,
        end: Float,
        duration: Long,
        listener: AnimationListener
    ): Animator {
        // 判断是否是从隐藏(start=0)到展开(end=1)的状态转换
        if (start == 0f && end == 1f) {
            return ValueAnimator.ofFloat(start, end).apply {
                this.duration = customDuration
                // 控制BottomSheet的translationY实现滑动效果
                addUpdateListener { anim ->
                    val progress = anim.animatedValue as Float
                    view.translationY = (1 - progress) * view.height
                }
                // 回调Behavior的动画监听
                addListener(object : Animator.AnimatorListener {
                    override fun onAnimationStart(anim: Animator) = listener.onAnimationStart()
                    override fun onAnimationEnd(anim: Animator) = listener.onAnimationEnd()
                    override fun onAnimationCancel(anim: Animator) = listener.onAnimationCancel()
                    override fun onAnimationRepeat(anim: Animator) = listener.onAnimationRepeat()
                })
            }
        }
        // 其他状态转换(比如展开到隐藏)使用默认动画
        return super.createAnimation(view, start, end, duration, listener)
    }
}

步骤2:在布局中使用自定义Behavior

把布局里默认的BottomSheetBehavior替换成你自定义的类:

<LinearLayout
    android:id="@+id/bottom_sheet_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_behavior="com.your.package.name.SlowBottomSheetBehavior">

    <!-- 这里放你的BottomSheet内容 -->

</LinearLayout>

方案二:通过反射修改默认Spring动画参数

如果不想重写Behavior,可以尝试反射修改默认的Spring动画参数(注意:反射依赖内部实现,可能随库版本变化失效)。

默认的BottomSheet使用SpringAnimation,调整它的stiffness(刚度)和dampingRatio(阻尼比)可以改变动画速度:

import com.google.android.material.bottomsheet.BottomSheetBehavior
import android.view.View
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce

// 获取BottomSheetBehavior实例
val bottomSheetView: View = findViewById(R.id.bottom_sheet_container)
val behavior = BottomSheetBehavior.from(bottomSheetView)

// 反射获取内部的SpringAnimation对象
try {
    val field = BottomSheetBehavior::class.java.getDeclaredField("mSpringAnimation")
    field.isAccessible = true
    val springAnim = field.get(behavior) as SpringAnimation

    // 降低刚度(值越小,动画越慢),默认是SpringForce.STIFFNESS_MEDIUM(1500f)
    springAnim.spring.stiffness = 500f
    // 调整阻尼比(值越大,弹跳越少),默认是SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY(0.5f)
    springAnim.spring.dampingRatio = 0.7f
} catch (e: Exception) {
    // 反射失败时降级处理
    e.printStackTrace()
}

注意事项

  • 如果你需要调整STATE_EXPANDED到STATE_HIDDEN的动画速度,只需在方案一的createAnimation方法中增加对start=1f && end=0f的判断即可。
  • 方案一的自定义动画要确保translationY的计算正确,否则会出现滑动异常。

内容的提问来源于stack exchange,提问作者Prabhashankar Kannapan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:59:45