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
相关产品推荐
相关产品推荐

