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

Android实现钟摆效果环形进度条及控件层叠方案咨询

Android实现带钟摆动效的双层环形进度条

1. 双进度条层叠问题解决

LinearLayout本身是线性顺序排列子View,天然不支持层叠;之前用RelativeLayout没实现层叠是因为属性用错,layout_alignTop是让两个控件顶部对齐,不是中心重合。
直接用FrameLayout或者ConstraintLayout作为父容器,把两个环形进度条都设置为居中对齐,就能实现完美同心叠放,参考布局代码:

<FrameLayout
    android:id="@+id/progress_container"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">

    <com.mikhaellopez.circularprogressbar.CircularProgressBar
        android:id="@+id/circularProgressBar"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        app:cpb_background_progressbar_color="#F8BB3B"
        app:cpb_background_progressbar_width="8dp"
        app:cpb_progress_direction="to_right"
        app:cpb_progressbar_color="#FFFFFF"
        app:cpb_progressbar_width="8dp"
        app:cpb_progress="25"
        app:cpb_round_border="true" />

    <com.mikhaellopez.circularprogressbar.CircularProgressBar
        android:id="@+id/circularProgressBar1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        app:cpb_background_progressbar_color="#F8BB3B"
        app:cpb_background_progressbar_width="5dp"
        app:cpb_progress_direction="to_right"
        app:cpb_progressbar_color="#FFFFFF"
        app:cpb_progressbar_width="5dp"
        app:cpb_progress="15"
        app:cpb_round_border="true" />
</FrameLayout>

2. 钟摆摆动动效实现

常用的开源CircularProgressBar本身只支持进度值变化动画,没有内置整体摆动能力,不需要修改库源码,直接给包裹两个进度条的父容器加属性动画即可实现钟摆效果:

  • 钟摆动效本质是控件围绕中心做小角度左右往复旋转,用减速插值器模拟真实钟摆的重力阻尼感,比匀速动画效果自然很多
  • 动画只需要加在父容器上,两个环形进度条会同步摆动,不需要分别做动画,避免出现不同步问题
    核心实现代码(Kotlin):
private fun startPendulumAnim(targetContainer: View) {
    // 摆动最大角度,可根据实际视觉效果调整
    val maxSwingAngle = 25f
    ObjectAnimator.ofFloat(targetContainer, View.ROTATION, -maxSwingAngle, maxSwingAngle).apply {
        duration = 350 // 单趟摆动时长
        repeatCount = ValueAnimator.INFINITE
        repeatMode = ValueAnimator.REVERSE
        // 减速插值器,模拟钟摆到端点时速度变慢的物理效果
        interpolator = DecelerateInterpolator()
        start()
    }
}

// 页面onCreate阶段调用即可,传入外层FrameLayout
// startPendulumAnim(findViewById(R.id.progress_container))

3. 效果优化建议

  • 如果要完全匹配参考动效里进度端点的轻微回弹感,可以在摆动动画执行的同时,给两个进度条的进度值加±2的小范围同步波动,动画节奏和摆动保持一致即可
  • 不推荐用layer-list实现:XML drawable实现的动画灵活度低、帧率表现差,后续修改进度值、调整动效参数的维护成本很高
  • 如果需要在环形中心加图标、文字,直接作为子View加入外层FrameLayout,设置android:layout_gravity="center"即可,会自动跟随整体一起摆动

内容的提问来源于stack exchange,提问作者Ron Weasley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:24:33