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

Android 自定义圆形进度条

2017-11-30 20:27 344 查看
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import com.example.customedemo2.view.CircleProgressView;

public class MainActivity extends AppCompatActivity {

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

CircleProgressView circleProgress = (CircleProgressView) findViewById(R.id.circleView);

//创建并开启线程
new Thread(circleProgress).start();

}
}
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 android.widget.Switch;

import com.example.customedemo2.R;

/**
* Created by 知足 on 2017/11/30.
*/

public class CircleProgressView extends View implements  Runnable{

//内圆环半径
private int innerCircleReadius = 100;
//画内部实心圆的画笔
private Paint innerPaint;
//画外部实心圆的笔
private Paint outCircleRingPaint;

//默认的外部圆环宽度
private int outCircleWidth = 20;
//绘制文本内容的笔
private Paint mTextPain;

//圆的中心点
private int centerX;
private int centerY;

//圆环的半径
private int outRingRadius;
private RectF rectF;

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

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

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

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

public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

//关联我们所声明的自定义属性

TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleProgressView, defStyleAttr, 0);

//获取属性
//获取内圆半径
innerCircleReadius= ta.getInt(R.styleable.CircleProgressView_innerCircleRadius, innerCircleReadius);

init();

//释放资源
ta.recycle();
}

/***
* 创建一个初始化画笔的方法
* 用于封装画笔相关设置
* */
private void  init(){

innerPaint = new Paint();
//设置画笔颜色
innerPaint.setColor(Color.parseColor("#d5982e"));
//设置抗拒齿
innerPaint.setAntiAlias(true);

//创建画外部圆环的画笔
outCircleRingPaint = new Paint();
outCircleRingPaint.setColor(Color.parseColor("#2a982e"));
//设置是否填充圆
outCircleRingPaint.setStyle(Paint.Style.STROKE);
//设置描述宽度(圆环宽度)
outCircleRingPaint.setStrokeWidth(outCircleWidth);
outCircleRingPaint.setAntiAlias(true);
//设置这个角
outCircleRingPaint.setStrokeCap(Paint.Cap.ROUND);

//创建文字画笔
mTextPain = new Paint();
//设置大小
mTextPain.setTextSize(50);
}

@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 ://wrap_content
{
width=innerCircleReadius * 2 +outCircleWidth * 2;
}
break;
case MeasureSpec.EXACTLY://match_parent
{
e371
width=widthSize;
}
break;
}

switch(heightMode){
case  MeasureSpec.UNSPECIFIED :
{
//很少用
}
break;
case MeasureSpec.AT_MOST ://wrap_content
{
//精准模式
height=innerCircleReadius * 2 + outCircleWidth * 2;
}
break;
case MeasureSpec.EXACTLY : //math_parent
{
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;

//圆环的半径
outRingRadius= w / 2 -outCircleWidth;

//确定圆环的绘制区域
rectF=new RectF();

rectF.left=centerX - outRingRadius;
rectF.top=centerY - outRingRadius;

rectF.right = centerX +outRingRadius;

rectF.bottom = centerY +outRingRadius;
}

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

/**
* 这是一个绘制图形界面的方法
* @param canvas 画布
*/

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

drawInnerCircle(canvas);
drawOutCircleRing(canvas);

dreawText(canvas);

}

/**
* 绘制文本
* @param canvas
*/
private  void  dreawText(Canvas canvas){
String des= progress + "%";

//得到文字的宽度与高度

Paint.FontMetrics fm=new Paint.FontMetrics();

//得到文字的高度
int tetHeight =(int) Math.ceil(fm.descent - fm.ascent);
//得到文字的宽度
int textWidth = (int) mTextPain.measureText(des, 0, des.length());

canvas.drawText(des,getWidth()/2-(textWidth /2),getHeight()/2 -(tetHeight/2),mTextPain);
}

/**
* 画内部实心圆
* @param canvas
*/
private void  drawInnerCircle(Canvas canvas){
canvas.drawCircle(getWidth()/2,getHeight()/2,innerCircleReadius,innerPaint);
}
/**
* 画外圆环
* @param canvas
*/
private void  drawOutCircleRing(Canvas canvas){
// 1 / 100 = 0 2 / 100 =  100%  1 *   1 2  3  4  5

//canvas.drawArc(getWidth() / 2 -
// innerCircleRadius,getHeight() /
// 2 - innerCircleRadius,getWidth() / 2 +
// innerCircleRadius,getHeight() / 2 +
// innerCircleRadius,-90,(progress * 360) /
// totalProgress,false,outCircleRingPaint);
canvas.drawArc(rectF,-90,(progress * 360)/ totalProgress,false,outCircleRingPaint);
}

@Override
public void run() {
while (true){
if(progress<100){
progress++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
postInvalidate();
}else{
progress=0;
}

}
}
}


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

<com.example.customedemo2.view.CircleProgressView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/circleView"
test:innerCircleRadius="300"
/>

</LinearLayout>


attrs
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgressView">

<attr name="innerCircleRadius" format="integer"/>

</declare-styleable>
</resources>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: