您的位置:首页 > 其它

自定义View之简单自定义圆形进度条

2017-03-06 00:42 531 查看
达到的效果如下:



从上面的效果可以看出,主要有以下几个自定义属性:

1、背景颜色

2、进度扇形颜色

3、半径

4、起始角度

因此,在attrs.xml中定义如下属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SimpleRoundProgressBar">
<attr format="color" name="roundColor"/>
<attr format="color" name="roundProgressColor"/>
<attr format="dimension" name="circleRadius"/>
<attr format="integer" name="startAngle"/>
</declare-styleable>
</resources>


下面是SimpleRoundProgressBar代码,在onMeasure当中确定view的大小,在onDraw来进行绘制。

package com.easyliu.demo.customizeview;

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.view.View;

/**
* Created by easyliu on 2017/2/24.
*/

public class SimpleRoundProgressBar extends View {
private Paint mPaint;//画笔
private RectF mRectF;//扇形绘制的矩形范围
private int mRoundColor;//圆环的颜色
private int mRoundProgressColor; //进度条的颜色
private float mRadius;//半径
private int mWidth;  //宽度
private int mHeight; //高度
private int mCenterX; //中心X坐标
private int mCenterY; //中心Y坐标
private int mStartAngle; //初始角度
private int mSweepAngle; //扫过的角度
private static final int DEFAULT_INIT_ANGLE = 0;//默认的初始化角度
private static final int DEFAULT_RADIUS = 10;//默认的半径

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

public SimpleRoundProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public SimpleRoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint();
mRectF = new RectF();
TypedArray typedArray =
context.obtainStyledAttributes(attrs, R.styleable.SimpleRoundProgressBar);
mRoundColor = typedArray.getColor(R.styleable.SimpleRoundProgressBar_roundColor, Color.GRAY);
mRoundProgressColor =
typedArray.getColor(R.styleable.SimpleRoundProgressBar_roundProgressColor, Color.RED);
mRadius =
typedArray.getDimension(R.styleable.SimpleRoundProgressBar_circleRadius, DEFAULT_RADIUS);
mStartAngle =
typedArray.getInteger(R.styleable.SimpleRoundProgressBar_startAngle, DEFAULT_INIT_ANGLE);
typedArray.recycle();
}

@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);

//如果为确定值
if (heightMode == MeasureSpec.EXACTLY) {
mHeight = heightSize;
} else {
//如果为wrap_content,高度为半径大小乘以2,注意padding
mHeight = (int) (mRadius * 2) + getPaddingTop() + getPaddingBottom();
}

//如果为确定值
if (widthMode == MeasureSpec.EXACTLY) {
mWidth = widthSize;
mHeight=mWidth;//宽和高相等
} else {
//如果为wrap_content,宽度为半径大小乘以2,注意padding
mWidth = (int) (mRadius * 2) + getPaddingLeft() + getPaddingRight();
}

//设置视图的大小
setMeasuredDimension(mWidth, mHeight);
}

@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(mRoundColor);
mPaint.setAntiAlias(true);
mCenterX = mWidth / 2;
mCenterY = mHeight / 2;
//注意处理padding
mRadius = (mWidth - getPaddingLeft() - getPaddingRight()) / 2;
//画圆
canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
mPaint.setColor(mRoundProgressColor);
//注意处理padding
mRectF.left = getPaddingLeft();
mRectF.right = mWidth - getPaddingRight();
mRectF.top = getPaddingTop();
mRectF.bottom = mHeight - getPaddingBottom();
//画扇形
canvas.drawArc(mRectF, (float) mStartAngle, mSweepAngle, true, mPaint);
}

public int getRoundColor() {
return mRoundColor;
}

public void setRoundColor(int roundColor) {
this.mRoundColor = roundColor;
}

/**
* 得到初始角度
*/
public synchronized int getStartAngle() {
return mStartAngle;
}

/**
* 设置初始角度
*/
public synchronized void setStartAngle(int startAngle) {
if (startAngle < -360) {
throw new IllegalArgumentException("the angle can not less than -360");
}
if (startAngle > 360) {
throw new IllegalArgumentException("the angle can not larger than 360");
}
this.mStartAngle = startAngle;
}

/**
* 得到扫过的角度
*/
public synchronized int getSweepAngle() {
return mSweepAngle;
}

/**
* 设置扫过的角度,相对于起始点
*
* @param sweepAngle 0~360
*/
public synchronized void setSweepAngle(int sweepAngle) {
if (sweepAngle < 0) {
throw new IllegalArgumentException("the angle can not less than 0");
}
if (sweepAngle > 360) {
throw new IllegalArgumentException("the angle can not larger than 360");
}
this.mSweepAngle = sweepAngle;
postInvalidate();
}
}


定义好了之后就可以使用了,首先是xml文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:easyliu="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.easyliu.demo.customizeview.RoundProgressBarActivity"
>

<com.easyliu.demo.customizeview.SimpleRoundProgressBar
android:id="@+id/progress_demo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:padding="10dp"
easyliu:circleRadius="50dp"
easyliu:roundColor="#5F000000"
easyliu:roundProgressColor="#ff8d33"
/>

<com.easyliu.demo.customizeview.SimpleRoundProgressBar
android:id="@+id/progress_demo2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/progress_demo"
android:padding="10dp"
easyliu:circleRadius="60dp"
easyliu:roundColor="@color/colorPrimary"
easyliu:roundProgressColor="@color/colorAccent"
/>

</RelativeLayout>


然后是Activity代码,在代码中使用定时器来定时更新进度即可。

package com.easyliu.demo.customizeview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.Timer;
import java.util.TimerTask;

public class RoundProgressBarActivity extends AppCompatActivity {
private int mCurrentAngle = 0;
private SimpleRoundProgressBar mRoundProgressBar1;
private SimpleRoundProgressBar mRoundProgressBar2;

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress_bar);
initViews();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override public void run() {
mCurrentAngle++;
mRoundProgressBar1.setSweepAngle(mCurrentAngle);
mRoundProgressBar2.setSweepAngle(mCurrentAngle);
if (mCurrentAngle >= 360) {
mCurrentAngle = 0;
}
}
}, 0, 20);
}
private void initViews(){
mRoundProgressBar1 =
(SimpleRoundProgressBar) findViewById(R.id.progress_demo);
mRoundProgressBar1.setStartAngle(-90);
mRoundProgressBar2= (SimpleRoundProgressBar) findViewById(R.id.progress_demo2);
mRoundProgressBar2.setStartAngle(0);
}
}


这样就完成了一个简单的圆形进度条的自定义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐