AndroidUI系列 - View实现圆形进度条

我就不从canvas和paint开始说了,onMeasure,onLayout,onDraw这些方法的介绍和源码解析。网上一搜很多。一篇解释不清楚,多看几篇。话不多说了,先看看效果吧。

这里写图片描述

这里写图片描述

做成gif显示会有问题。我们先来分析一下需要什么数据、
1、需要一个进度
2、需要进度条基本信息,颜色,宽度,大小
3、需要字体大小,颜色

这里写图片描述

那么就来看看具体逻辑。

package com.example.administrator.myapplication.circle;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.example.administrator.myapplication.R;

/**
 * Created by ShuWen on 2017/6/10.
 */

public class CircleProgressBar extends View {

    //进度条背景色
    private int mCircleBgColor = Color.BLUE;
    //进度条文字展示颜色
    private int mTextColor = Color.GRAY;
    //进度条宽度
    private float mCircleWidth = 50;
    //进度条颜色
    private int mProgressColor = Color.GREEN;
    //进度条展示文字大小
    private float mTextSize = 50;

    private int progress;
    private int max = 100;


    private Paint paint = new Paint();


    public CircleProgressBar(Context context) {
        super(context);
        init(context,null);
    }

    public CircleProgressBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public CircleProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    public void init(Context context,AttributeSet attrs){
        TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.CircleProgressBar);
        mCircleBgColor = array.getColor(R.styleable.CircleProgressBar_mCircleBgColor,Color.BLUE);
        mTextColor = array.getColor(R.styleable.CircleProgressBar_mTextColor,Color.GRAY);
        mProgressColor = array.getColor(R.styleable.CircleProgressBar_mProgressColor,Color.GREEN);
        mCircleWidth = array.getDimension(R.styleable.CircleProgressBar_mCircleWidth,50);
        mTextSize = array.getDimension(R.styleable.CircleProgressBar_mTextSize,50);

        array.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画背景
        paint.setColor(mCircleBgColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(mCircleWidth);
        int center = getWidth() / 2;

        int radius = (int) (center - mCircleWidth / 2);
        canvas.drawCircle(center,center,radius,paint);

        //写文字
        int percent = (int) (( progress / (float)max ) * 100);
        String percentStr = percent + "%";
        paint.setStrokeWidth(0);
        paint.setColor(mTextColor);
        paint.setTextSize(mTextSize);
        Paint.FontMetricsInt fm = paint.getFontMetricsInt();
        if (progress != 0){
            canvas.drawText(percentStr,center - paint.measureText(percentStr) / 2,
                    center + (fm.bottom - fm.top) / 2 -fm.bottom,paint);
        }

        //画弧形
        RectF oval = new RectF(center - radius,center - radius,center + radius,center + radius);
        paint.setStrokeWidth(mCircleWidth);
        paint.setColor(mProgressColor);
        paint.setStrokeCap(Paint.Cap.ROUND);

        canvas.drawArc(oval,0,360 * progress/max,false,paint);
    }

    //设置进度条
    public void setProgress(int progress){
        if (progress > max){
            progress = max;
        }
        if (progress <= max){
            this.progress = progress;
            postInvalidate();
        }
    }
}

需要自定义的属性。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircleProgressBar">
        <attr name="mCircleBgColor" format="color"/>
        <attr name="mTextColor" format="color"/>
        <attr name="mCircleWidth" format="dimension"/>
        <attr name="mTextSize" format="dimension"/>
        <attr name="mProgressColor" format="color"/>
    </declare-styleable>
</resources>

详细布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="com.example.administrator.myapplication.MainActivity">

<com.example.administrator.myapplication.circle.CircleProgressBar
        android:id="@+id/progressBar"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:mCircleBgColor="#ff00ff"
        app:mCircleWidth="10dp"
        app:mProgressColor="#00ff00"
        app:mTextColor="#000"
        app:mTextSize="20dp"
        />
</RelativeLayout>

ManActivity,开启一个线程,休眠100ms,重新设置进度。

package com.example.administrator.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.example.administrator.myapplication.circle.CircleProgressBar;
import com.example.administrator.myapplication.flow.WaterFallLayout;

import java.util.Random;


public class MainActivity extends AppCompatActivity {

    WaterFallLayout waterfall;

    private static int IMG_COUNT = 5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final CircleProgressBar progressBar = (CircleProgressBar) findViewById(R.id.progressBar);
        progressBar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        int progress = 0;
                        while (progress <= 100){
                            progress += 2;

                            progressBar.setProgress(progress);
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
            }
        });
    }



}

圆形进度条呢,网上其实很多。写的也很详细,我这里只是做一个学习笔记。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要创建一个自定义的分段式圆形进度条,您可以按照以下步骤进行操作: 1. 创建一个自定义的View类,继承自View或者ProgressBar类。假设这个类叫做SegmentedCircularProgressBar。 2. 在SegmentedCircularProgressBar类中,定义一个用于存储分段信息的数据结构,比如使用一个List来保存每个分段的进度。 3. 添加一个方法来设置分段信息,比如setSegments(List<Float> segmentList),其中segmentList是一个包含每个分段进度的列表。 4. 在SegmentedCircularProgressBar的onDraw方法中,根据分段信息绘制圆形进度条。可以使用Canvas和Paint类来实现绘制。 5. 在onMeasure方法中,根据实际需要设置View的大小。 6. 实现一些其他的方法,比如更新进度、获取分段信息等。 7. 在布局文件中使用自定义的SegmentedCircularProgressBar,并设置相应的属性和样式。 以下是一个简单的示例代码,用于帮助您开始创建自定义的分段式圆形进度条: ```java public class SegmentedCircularProgressBar extends View { private List<Float> segmentList; public SegmentedCircularProgressBar(Context context) { super(context); init(); } public SegmentedCircularProgressBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { // 初始化一些变量和样式 } public void setSegments(List<Float> segmentList) { this.segmentList = segmentList; invalidate(); // 通知View进行重绘 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 根据分段信息绘制圆形进度条 // 使用Canvas和Paint进行绘制操作 } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 根据实际需要设置View的大小 } // 实现其他方法,比如更新进度、获取分段信息等 } ``` 请根据您的需求进行相应的扩展和修改。希望对您有所帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值