如何实现图示布局?求助中心环形ProgressBar动画方案
实现环绕头像的环形进度条(带动画)
核心实现思路
- 采用双层环形绘制:底层为静态背景环,上层为动态进度环,通过逐帧绘制实现进度动画
- 中心放置主头像,进度环外围均匀分布小头像(通过计算圆周坐标动态添加)
代码实现步骤
1. 自定义环形进度View
继承View,在onDraw中绘制环形进度,配合ValueAnimator实现平滑动画:
public class CircleProgressView extends View { private Paint bgPaint, progressPaint; private float progress = 0f; private int circleWidth = 20; // 环形宽度 public CircleProgressView(Context context) { super(context); init(); } private void init() { bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); bgPaint.setColor(Color.parseColor("#E0E0E0")); bgPaint.setStyle(Paint.Style.STROKE); bgPaint.setStrokeWidth(circleWidth); progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG); progressPaint.setColor(Color.parseColor("#FF4081")); progressPaint.setStyle(Paint.Style.STROKE); progressPaint.setStrokeWidth(circleWidth); progressPaint.setStrokeCap(Paint.Cap.ROUND); // 圆角进度端点 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int centerX = getWidth() / 2; int centerY = getHeight() / 2; int radius = Math.min(centerX, centerY) - circleWidth / 2; // 绘制背景环 canvas.drawCircle(centerX, centerY, radius, bgPaint); // 绘制进度环(从顶部-90度起点开始) canvas.drawArc(centerX - radius, centerY - radius, centerX + radius, centerY + radius, -90, progress * 3.6f, false, progressPaint); } // 设置目标进度并启动动画 public void setProgress(float targetProgress) { ValueAnimator animator = ValueAnimator.ofFloat(progress, targetProgress); animator.setDuration(1500); animator.addUpdateListener(animation -> { progress = (float) animation.getAnimatedValue(); invalidate(); }); animator.start(); } }
2. 布局结构(ConstraintLayout示例)
组合主头像、环形进度View与外围头像容器:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 中心主头像 --> <ImageView android:id="@+id/mainAvatar" android:layout_width="120dp" android:layout_height="120dp" android:src="@drawable/main_avatar" app:layout_constraintCenterInParent="true" /> <!-- 环形进度View --> <com.yourpackage.CircleProgressView android:id="@+id/circleProgress" android:layout_width="240dp" android:layout_height="240dp" app:layout_constraintCenterInParent="true" /> <!-- 外围小头像容器 --> <LinearLayout android:id="@+id/avatarContainer" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintCenterInParent="true" /> </androidx.constraintlayout.widget.ConstraintLayout>
3. 动态添加外围小头像
通过圆周坐标计算,将小头像均匀分布在进度环外围:
private void addSurroundAvatars() { LinearLayout container = findViewById(R.id.avatarContainer); int avatarCount = 8; // 外围头像数量 int radius = 140; // 头像中心到主中心的距离 int centerX = container.getWidth() / 2; int centerY = container.getHeight() / 2; for (int i = 0; i < avatarCount; i++) { float angle = (float) (2 * Math.PI / avatarCount * i); int x = (int) (centerX + radius * Math.cos(angle)); int y = (int) (centerY + radius * Math.sin(angle)); ImageView avatar = new ImageView(this); avatar.setLayoutParams(new ViewGroup.LayoutParams(40, 40)); avatar.setImageResource(R.drawable.small_avatar); avatar.setX(x - 20); // 偏移至头像中心 avatar.setY(y - 20); container.addView(avatar); } }
4. 启动进度动画
在页面初始化时调用,设置目标进度:
CircleProgressView progressView = findViewById(R.id.circleProgress); progressView.setProgress(75); // 目标进度范围0-100
资源处理说明
- 主头像、外围小头像直接替换为设计师提供的资源
- 环形颜色、宽度、动画时长可直接在自定义View中调整,也可通过自定义属性实现配置化
内容的提问来源于stack exchange,提问作者Prabhu M
相关产品推荐
相关产品推荐

