Android:如何为带遮罩的圆形ProgressBar添加动画?
嘿,我明白你想要实现的是一个被限制在自定义形状内、还带动画效果的圆形ProgressBar,结合你已经掌握的基础圆形ProgressBar代码,我来一步步帮你搞定这个需求~
实现自定义形状内的动画圆形ProgressBar
1. 先搞定自定义遮罩形状
首先我们需要一个自定义形状作为遮罩,把ProgressBar的显示区域限制在这个形状里。比如假设你想要五角星形状,先创建shape_mask_star.xml放在drawable目录:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="polygon"> <!-- 这里以五角星为例,你可以替换成任意自定义路径的形状 --> <path android:pathData="M50,0 L61,30 L95,30 L68,50 L79,80 L50,60 L21,80 L32,50 L5,30 L39,30 Z" android:fillColor="#FF000000"/> </shape>
2. 布局层叠实现形状裁剪
我们用FrameLayout把基础ProgressBar和遮罩层叠在一起,通过混合模式实现裁剪效果:
<FrameLayout android:layout_width="120dp" android:layout_height="120dp"> <!-- 你已有的基础圆形ProgressBar --> <ProgressBar android:id="@+id/customProgressBar" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:indeterminate="false" android:max="6000" android:progress="0" android:progressDrawable="@drawable/shape_ring_blue_progress" android:layout_gravity="center"/> <!-- 遮罩层:用ImageView加载自定义形状,通过混合模式裁剪ProgressBar --> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/shape_mask_star" android:scaleType="centerCrop" android:layerType="software" android:backgroundTintMode="src_in"/> </FrameLayout>
如果是Android 8.0+,也可以用更高效的ViewOutlineProvider代码实现裁剪:
// 在Activity/Fragment中设置 val progressBar = findViewById<ProgressBar>(R.id.customProgressBar) val outlineProvider = object : ViewOutlineProvider() { override fun getOutline(view: View, outline: Outline) { // 自定义形状的Path,这里还是五角星示例 val path = Path() path.moveTo(60f, 0f) path.lineTo(73f, 36f) path.lineTo(114f, 36f) path.lineTo(82f, 60f) path.lineTo(95f, 96f) path.lineTo(60f, 72f) path.lineTo(25f, 96f) path.lineTo(38f, 60f) path.lineTo(6f, 36f) path.lineTo(47f, 36f) path.close() outline.setConvexPath(path) } } progressBar.outlineProvider = outlineProvider progressBar.clipToOutline = true
3. 添加平滑的进度动画
用ValueAnimator给ProgressBar加个自然的进度动画:
val progressBar = findViewById<ProgressBar>(R.id.customProgressBar) val targetProgress = 4500 // 目标进度,比如总进度6000的75% val animator = ValueAnimator.ofInt(0, targetProgress) animator.duration = 1500 // 动画时长1.5秒 animator.addUpdateListener { animation -> val currentProgress = animation.animatedValue as Int progressBar.progress = currentProgress } // 加个插值器让动画更丝滑 animator.interpolator = AccelerateDecelerateInterpolator() animator.start()
4. 优化基础ProgressBar的Drawable(可选)
给你的shape_ring_blue_progress.xml补全并优化,让进度环更美观:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 背景环 --> <item> <shape android:innerRadiusRatio="2.5" android:shape="ring" android:thicknessRatio="15" android:useLevel="false"> <solid android:color="#E0E0E0"/> </shape> </item> <!-- 进度环:加渐变效果更高级 --> <item> <shape android:innerRadiusRatio="2.5" android:shape="ring" android:thicknessRatio="15" android:useLevel="true"> <gradient android:startColor="#2196F3" android:endColor="#1976D2" android:type="sweep"/> </shape> </item> </layer-list>
这样一来,你的ProgressBar就会被限制在自定义形状内,同时还有平滑的进度动画啦!如果要换其他形状,只需要修改遮罩的Path或者Outline的路径就行。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

