您的位置:首页 > 移动开发 > Android开发

Android自定义View实现带百分比圆形进度条

2017-12-03 23:06 666 查看
自定义View代码

import android.content.Context;
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 android.widget.Button;

import com.google.fw.R;

/**
* author:Created by ZhangPengFei on 2017/12/3.
*/

public class CircleTime extends View implements Runnable {

private Button btnBegin;
private Paint innerPaint;//内部圆
private Paint outPaint;//外部圆环
private Paint textPaint;//文字
private int outCircleWidth = 20;//设置外部圆环宽度
private int innerCircleRadius = 130;//设置内部圆半径
private int min = 0;//设置初始值
private int max = 100;//设置百分比最大值
private int centerX;
private int centerY;
private int radiuWidth;
private RectF rectF;

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

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

public CircleTime(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();//初始化视图
initPaint();//初始化画笔
}

private void initPaint() {
/**
* 创建内部圆
*/
innerPaint = new Paint();//创建内部圆画笔
innerPaint.setAntiAlias(true);//设置抗锯齿
innerPaint.setColor(Color.BLACK);//设置颜色
/**
* 创建外部圆环
*/
outPaint = new Paint();//创建外部圆环画笔
outPaint.setAntiAlias(true);//设置抗锯齿
outPaint.setColor(Color.RED);//设置颜色
outPaint.setStyle(Paint.Style.STROKE);//设置圆环角度
outPaint.setStrokeWidth(outCircleWidth);//设置圆环的宽度
/**
* 创建百分比文字的画笔
*/
textPaint = new Paint();//创建文字画笔
textPaint.setTextSize(35);//设置文字大小
textPaint.setColor(Color.WHITE);
}

/**
* 精准测量
* 设置圆心+圆环的大小(正方形)
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@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:{
//设置宽度为内圆半径*2加上圆环两边的宽度
width = innerCircleRadius*2 + outCircleWidth*2;
}
break;
case MeasureSpec.EXACTLY:{
//将整个圆的宽度赋值给宽
width = widthSize;
}
break;
}
switch (heightMode){
case MeasureSpec.UNSPECIFIED:{

}
break;
case MeasureSpec.AT_MOST:{
//设置高度为内圆半径*2加上圆环两边的高度
height = innerCircleRadius*2 + outCircleWidth*2;
}
break;
case MeasureSpec.EXACTLY:{
//将整个圆的高度赋值给高
height = heightSize;
}
break;
}
//调用整合方法才可以进入测量模式,否则不进入测量模式
setMeasuredDimension(width,height);
}
//得到测量后的宽,高

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w / 2;
centerY = h / 2;
//内圆的半径
radiuWidth = w / 2 - outCircleWidth;
//        Log.i("asdasdasd", String.valueOf(radiuWidth));
rectF = new RectF();
rectF.left = centerX-radiuWidth-10;
rectF.right = centerX+radiuWidth+10;
rectF.top = centerY-radiuWidth-10;
rectF.bottom = centerY+radiuWidth+10;
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
onDrawInnerCircle(canvas);
onDrawOutCircle(canvas);
onDrawText(canvas);
}

/**
* 内部圆
* @param canvas
*/
private void onDrawInnerCircle(Canvas canvas) {
canvas.drawCircle(getWidth()/2,getHeight()/2,innerCircleRadius,innerPaint);
}

/**
* 外部圆环
* @param canvas
*/
private void onDrawOutCircle(Canvas canvas) {
canvas.drawArc(rectF,-90,(min*360)/max,false,outPaint);
}

/**
* 文字
* @param canvas
*/
private void onDrawText(Canvas canvas) {
String count = min + "%";
//得到文字的宽度和高度
Paint.FontMetrics fontMetrics = new Paint.FontMetrics();
//得到文字的宽度
int textWidth = (int) textPaint.measureText(count, 0, count.length());
//得到文字的高度
int textHeight = (int) Math.ceil(fontMetrics.descent - fontMetrics.ascent);
canvas.drawText(count,getWidth()/2-(textWidth/2),getHeight()/2-(textHeight/2),textPaint);
}

private void initView() {
View inflate = View.inflate(getContext(), R.layout.activity_circle, null);
btnBegin = (Button)inflate.findViewById(R.id.btnBegin);
}

@Override
public void run() {
while(min<=100){
min++;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
postInvalidate();
}
}
}


activity_main布局

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

<com.google.fw.view.CircleTime
android:id="@+id/ct"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnBegin"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</RelativeLayout>

MainActivity代码

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

import com.google.fw.view.CircleTime;

public class MainActivity extends AppCompatActivity {

private CircleTime ct;
private Button btnBegin;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ct = (CircleTime) findViewById(R.id.ct);
btnBegin = (Button) findViewById(R.id.btnBegin);
btnBegin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(ct).start();
}
});
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: