自定义view圆弧家百分比

本文介绍了一个自定义的Android视图组件——百分比圆环视图,该组件可以显示进度百分比,并通过动画效果实现动态更新。文章详细阐述了如何使用Paint绘制圆环和文本,以及如何通过Runnable接口更新进度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//新建的类的内容
package com.example.baifenbiyuanquan.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;

/**
 * author:Created by Chenxu on 2017/11/29.
 */

public class yuan extends View implements Runnable{

    private Paint inpaint;
    /**
     * 定义一个初始进度值
     */
    private int progress = 0;

    /**
     * 加载总进度
     */
    private int totalProgress = 100;

    /**
     * 内部圆环半斤
     */
    private int innerCircleRadius = 100;

    /**
     * 默认的外部圆环宽度
     */
    private int outCircleWidth = 20;
    private Paint outpaint;
    private Paint textpaint;

    public yuan(Context context) {
        this(context,null);
    }

    public yuan(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

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

    private void init(){
        //内部圆
        inpaint = new Paint();
        inpaint.setAntiAlias(true);
        //外部弧度
        outpaint = new Paint();
        outpaint.setAntiAlias(true);
        //文字属性
        textpaint = new Paint();
        //设置画笔颜色
        inpaint.setColor(Color.parseColor("#D5982E"));
        //设置是否填充圆
        outpaint.setStyle(Paint.Style.STROKE);
        //设置描边宽度(圆环宽度)
        outpaint.setStrokeWidth(outCircleWidth);
        //设置文字大小
        textpaint.setTextSize(35);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 画圆
        canvas.drawCircle(getWidth()/2,getHeight()/2,innerCircleRadius,inpaint);
        //画外围弧度
//        canvas.drawArc(getWidth() / 2 - innerCircleRadius,getHeight() / 2 - innerCircleRadius,getWidth() / 2 + innerCircleRadius,getHeight() / 2 + innerCircleRadius,-90,(progress * 360) / totalProgress,false,outpaint);

        RectF oval=new RectF();                     //RectF对象
        oval.left=getWidth()/2-100;                              //左边
        oval.top=getHeight()/2-100;                                   //上边
        oval.right=getWidth()/2+100;                             //右边
        oval.bottom=getHeight()/2+100;                                //下边
        canvas.drawArc(oval, -90, (progress*360)/100, false, outpaint);

//        RectF rectF = new RectF();
//        canvas.drawArc();

        //绘制文本
        String des = progress + "%";
        //得到文字的宽度与高度
        Paint.FontMetrics fm = new Paint.FontMetrics();
        //得到文字的高度
        int textHeight = (int)Math.ceil(fm.descent - fm.ascent);
        //的到文字宽度
        int textWidth = (int)textpaint.measureText(des,0,des.length());
        canvas.drawText(des,getWidth()/2 - (textWidth / 2),getHeight() / 2 - (textHeight/2),textpaint);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        /**
         * 测量三种模式
         * 精确的
         *
         * 至多 :
         *
         * 不确定的 : 用的很少,一般会用到它
         *
         */
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        //得到控件的宽高
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        //定义变量记录控件的宽高
        int width = 0;
        int height = 0;
        switch (widthMode){
            case MeasureSpec.UNSPECIFIED:
            {
                //很少用
            }
            break;
            case MeasureSpec.AT_MOST://match_parent
            {
                width = innerCircleRadius * 2 + outCircleWidth * 2;
            }
            break;
            case MeasureSpec.EXACTLY://wrap_content
            {
                width = widthSize;//至多有多大
            }
            break;

        }
        switch (heightMode) {
            case MeasureSpec.UNSPECIFIED: {
                //很少用
            }
            break;
            case MeasureSpec.AT_MOST://wrap_content
            {
                //精确模式
                height = innerCircleRadius * 2 + outCircleWidth * 2;
            }
            break;
            case MeasureSpec.EXACTLY://match_parent
            {
                height = heightSize;//至多有多大
            }
            break;
        }
        //必须调用,如果不调用的话,测量的这个高度会出现偏差
        setMeasuredDimension(width,height);
    }


    public void run() {
        while (true) {
            if (progress < 100) {
                progress++;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                postInvalidate();
            } else {
                progress = 0;
            }
        }
    }
}
//Main里面的回调,执行线程,让百分比动起来

Main的布局  cim.上面的类名

<com.example.md5.Yuan
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/yuan"/>
   

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        yuan viewById = (yuan) findViewById(R.id.circleView);
        new Thread(viewById).start();
    }
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值