Android自定义view圆形进度条

自定义一个类实现构造方法 重写方法
package test.bwie.com.baixinfei20171009;

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.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import static android.R.attr.x;
import static android.R.attr.y;

/**
* 自定义view
* Created by admin on 2017/10/9.
* 白新飞
*/

public class yuanhuan extends View {

/*private int cWdith;
private int ncolor;
private int wcolor;
private int ccolor;
private int textsize;
private String text;
private int textcolor;
private Paint p;*/
/**
 * 绘制百分比的圆,一共有四部分,分别是里面的文字、背景圆、默认圆环、开始绘制的圆环;
 * 思路:首先需要四支画笔, 设置画笔对应的属性等;
 */
/**
 * 绘制百分比的圆,一共有四部分,分别是里面的文字、背景圆、默认圆环、开始绘制的圆环;
 * 思路:首先需要四支画笔, 设置画笔对应的属性等;
 */
private Paint roundColorPaint;//外圆画笔
private Paint mCirclePaint;//中心园的画笔
private Paint mTextPaint;//文字的画笔
private Paint mArcPaint;//外圆环的画笔
private int mCircleX;//设置圆心x坐标
private int mCircleY;//设置圆心y坐标
private float mCurrentAngle;//当前角度
private RectF mArcRectF;//画中心园的外接矩形,用来画圆环用
private float mStartSweepValue;//圆环开始角度
private float mTargetPercent;//设置目标的百分比(也就是后台返回的数据)
private float mCurrentPercent;//当前百分比

private int mRadius;//圆的半径
private int mCircleBackground;//中间圆的背景颜色
private int mRingColor;//外圆环的颜色  第二次画圆的颜色
private int roundColor; //外圆环的颜色 第一次画圆的颜色
private int mTextSize;//字体大小
private int mTextColor;//字体颜色
public yuanhuan(Context context) {
    super(context);
    //初始化数据
    init(context);
}

public yuanhuan(Context context, AttributeSet attrs) {
    super(context, attrs);
    // 自定义属性,attr
    // 使用TypedArray
    //自定义属性 values/attr
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PercentageRing);
    //中间圆的背景颜色  默认 - 白色
    mCircleBackground = typedArray.getColor(R.styleable.PercentageRing_circleBackground, 0xffafb4db);
    //外圆环的颜色  默认 - 灰色
    roundColor = typedArray.getColor(R.styleable.PercentageRing_circleColor, 0xffffffff);
    //外圆环的颜色  动态画圆 - 默认-红色
    mRingColor = typedArray.getColor(R.styleable.PercentageRing_ringColor, 0xffafb4db);
    //中间圆的半径 默认为80
    mRadius = typedArray.getInt(R.styleable.PercentageRing_radius, 80);
    //字体颜色 默认 - 灰色
    mTextColor = typedArray.getColor(R.styleable.PercentageRing_textColor, 0xffafb4db);
    //最后一定要调用这个 释放掉TypedArray
    typedArray.recycle();
    //初始化数据
    init(context);
}

public yuanhuan(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public yuanhuan(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init(context);
}
private void init(Context context){
    //圆环开始角度 -90° 正北方向
    mStartSweepValue = -90;
    //当前角度
    mCurrentAngle = 0;
    //当前百分比
    mCurrentPercent = 0;
    //设置中心园的画笔
    mCirclePaint = new Paint();
    mCirclePaint.setAntiAlias(true);
    mCirclePaint.setColor(mCircleBackground);
    mCirclePaint.setStyle(Paint.Style.FILL);
    //设置文字的画笔
    mTextPaint = new Paint();
    mTextPaint.setColor(mTextColor);
    mTextPaint.setAntiAlias(true);
    mTextPaint.setStyle(Paint.Style.FILL);
    mTextPaint.setStrokeWidth((float) (0.025*mRadius));
    mTextPaint.setTextSize(mRadius/2);
    mTextPaint.setTextAlign(Paint.Align.CENTER);
    //设置外圆环的画笔
    mArcPaint = new Paint();
    roundColorPaint = new Paint();
    roundColorPaint.setColor(roundColor);
    mArcPaint.setAntiAlias(true);
    mArcPaint.setColor(mRingColor);
    mArcPaint.setStyle(Paint.Style.STROKE);
    mArcPaint.setStrokeWidth((float) (0.075*mRadius));

    //获得文字的字号 因为要设置文字在圆的中心位置
    mTextSize = (int) mTextPaint.getTextSize();

}
//主要是测量wrap_content时候的宽和高,因为宽高一样,只需要测量一次宽即可,高等于宽
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(measure(widthMeasureSpec), measure(widthMeasureSpec));
    //设置圆心坐标
    mCircleX = getMeasuredWidth()/2;
    mCircleY = getMeasuredHeight()/2;
    //如果半径大于圆心横坐标,需要手动缩小半径的值,否则就画到外面去了
    if (mRadius>mCircleX) {
        //设置半径大小为圆心横坐标到原点的距离
        mRadius = mCircleX;
        mRadius = (int) (mCircleX-0.075*mRadius);
        //因为半径改变了,所以要重新设置一下字体宽度
        mTextPaint.setStrokeWidth((float) (0.025*mRadius));
        //重新设置字号
        mTextPaint.setTextSize(mRadius/2);
        //重新设置外圆环宽度
        mArcPaint.setStrokeWidth((float) (0.075*mRadius));
        //重新获得字号大小
        mTextSize = (int) mTextPaint.getTextSize();
    }
    //画中心园的外接矩形,用来画圆环用
    mArcRectF = new RectF(mCircleX-mRadius, mCircleY-mRadius, mCircleX+mRadius, mCircleY+mRadius);
}

//当wrap_content的时候,view的大小根据半径大小改变,但最大不会超过屏幕
private int measure(int measureSpec){
    int result=0;
    //1、先获取测量模式 和 测量大小
    //2、如果测量模式是MatchParent 或者精确值,则宽为测量的宽
    //3、如果测量模式是WrapContent ,则宽为 直径值 与 测量宽中的较小值;否则当直径大于测量宽时,会绘制到屏幕之外;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    if (specMode == MeasureSpec.EXACTLY) {
        result = specSize;
    }else {
        result =(int) (1.075*mRadius*2);
        if (specMode == MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
    }
    return result;

}

//开始画中间圆、文字和外圆环
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //1、画中间背景圆
    //2、画文字
    //3、画圆环
    //4、判断进度,重新绘制
    canvas.drawCircle(mCircleX, mCircleY, mRadius, roundColorPaint);
    canvas.drawText(String.valueOf(mCurrentPercent) + "%", mCircleX, mCircleY + mTextSize / 4, mTextPaint);
    canvas.drawArc(mArcRectF, mStartSweepValue, mCurrentAngle, false, mArcPaint);

    if (mCurrentPercent < mTargetPercent) {
        //当前百分比+1
        mCurrentPercent += 1;
        //当前角度+360
        mCurrentAngle += 3.6;
        //每10ms重画一次
        postInvalidateDelayed(10);
    } else if (mCurrentPercent == mTargetPercent) {
        //当前百分比+1
        mCurrentPercent = 0;
        //当前角度+360
        mCurrentAngle = 0;
        //每10ms重画一次
        postInvalidateDelayed(10);
        //canvas.drawRect(mArcRectF, mRingPaint);
    }
}
//设置目标的百分比
public void setTargetPercent(float percent){
    mTargetPercent = percent;
}

}


自定义属性

<resources>
    <declare-styleable name="PercentageRing">
        <attr name="circleColor" format="color"/>
        <attr name="radius" format="integer"/>
        <attr name="circleBackground" format="color"/>
        <attr name="ringColor" format="color"/>
        <attr name="textColor" format = "color"/>
    </declare-styleable> </resources>

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/test.bwie.com.baixinfei20171009"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="test.bwie.com.baixinfei20171009.MainActivity">

    <test.bwie.com.baixinfei20171009.yuanhuan
        android:id="@+id/recommend_progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:circleBackground="#00000000"
        android:layout_centerHorizontal="true"
        app:ringColor="#ffea4745"
        app:textColor="#ff999999"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/start"
        android:layout_below="@id/recommend_progressBar"
        android:text="开始"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/reset"
        android:layout_toRightOf="@id/start"
        android:layout_below="@id/recommend_progressBar"
        android:text="暂停"/>
</RelativeLayout>

MainActivity

package test.bwie.com.baixinfei20171009;

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

public class MainActivity extends AppCompatActivity {
private yuanhuan cc;
private Button start;
private Button resut;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start= (Button) findViewById(R.id.start);
resut= (Button) findViewById(R.id.reset);
cc= (yuanhuan) findViewById(R.id.recommend_progressBar);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cc.setTargetPercent(100);
cc.invalidate();
}
});
resut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cc.setTargetPercent(0);
cc.invalidate();
}
});

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值