很多时候我们需要用一个优美好看的圆之类的来表示进度或者选择程度,但是android自带的控件一般很难满足我们的需求,这时候就到自定义view登场啦!
文章结构:1.解析一个手动选择的程度圆的自定义view制作 2.解析一个圆环中的圆弧转动来表示进度的进度圆 (这两个例子已经帮各位写好调大小的方法了,复制即可使用)【接下来一段时间,本博主还会持续更新一系列的自定义view,敬请关注。】
先上图 可以看到上面的就是点击选择程度的圆,下面就是用圆弧旋转表示进度的进度圆
一、一个手动选择的程度圆的自定义view制作
1.先给出代码,在代码里面解析
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import com.demo.myview.R;
/**
* Created by ${符柱成} on 2016/8/20.
*/
public class ManualCircle extends View {
private Paint circlePaint, arcPaint, textPaint;
private RectF rectF;
int i = 0;
/**
* 圆环的宽度
*/
private int mCircleWidth;
private int centerCircleColor;
private int ringColor;
private int textColor;
public ManualCircle(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomProgressBar);
int n = typedArray.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.CustomProgressBar_circleWidth :
mCircleWidth = (int) typedArray.getDimension(attr, 0);
break;
case R.styleable.CustomProgressBar_centercircleColor :
centerCircleColor=typedArray.getColor(attr,0);
break;
case R.styleable.CustomProgressBar_ringColor :
ringColor=typedArray.getColor(attr,0);
break;
case R.styleable.CustomProgressBar_textColor :
textColor=typedArray.getColor(attr,0);
break;
}
}
typedArray.recycle();
initPaint();
}
private void initPaint() {
textPaint = new TextPaint(0);
textPaint.setColor(textColor);
textPaint.setTextSize(80);
textPaint.setTextAlign(Paint.Align.CENTER);
circlePaint = new Paint();
circlePaint.setColor(centerCircleColor);
arcPaint = new Paint();
arcPaint.setStyle(Paint.Style.STROKE);
arcPaint.setColor(ringColor);
rectF = new RectF();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float xy = getWidth() / 2;
float radius = xy - mCircleWidth;
rectF.left = xy - radius - mCircleWidth / 2;
rectF.top = xy - radius - mCircleWidth / 2;
rectF.right = xy + radius + mCircleWidth / 2;
rectF.bottom = xy + radius + mCircleWidth / 2;
arcPaint.setStrokeWidth(mCircleWidth);
canvas.drawCircle(xy, xy, radius, circlePaint);
int progress=i*10/36;
canvas.drawArc(rectF, 270, i, false, arcPaint);
canvas.drawText(String.valueOf(progress)+"%", xy, xy, textPaint);
}
/**
* 公开一个方法,可以更新弧线的度数,也就是选择程度啦,设置为单击一次就增加10%
*/
public void add() {
if (i >= 360) {
i = 36;
postInvalidate();
} else {
this.i += 36;
postInvalidate();
}
}
}
2.然后给出属性文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomProgressBar">
<attr name="circleWidth" format="dimension" />
<attr name="ringColor" format="color" />
<attr name="centercircleColor" format="color" />
<attr name="textColor" format="color" />
</declare-styleable>
<declare-styleable name="AutomaticCircleProgress">
<attr name="automaticCircleWidth" format="dimension" />
<attr name="automaticBottomRingColor" format="color" />
<attr name="automaticDrawRingColor" format="color" />
<attr name="automaticCentercircleColor" format="color" />
<attr name="automaticTextColor" format="color" />
</declare-styleable>
</resources>
3.接下来就是给出在xml中的调用啦:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context="com.demo.myview.progressCircle.ProgressCircleActivity">
<com.demo.myview.progressCircle.ManualCircle
android:id="@+id/myview"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_centerInParent="true"
app:centercircleColor="#FFFF00"
app:circleWidth="11dp"
app:ringColor="#008000"
app:textColor="#000000"></com.demo.myview.progressCircle.ManualCircle>
<com.demo.myview.progressCircle.AutomaticCircle
android:id="@+id/automaticCircle"
android:layout_width="160dp"
android:layout_height="160dp"
app:automaticBottomRingColor="#000000"
app:automaticCentercircleColor="#aaa"
app:automaticCircleWidth="20dp"
app:automaticDrawRingColor="#FFFFFF"
app:automaticTextColor="#FFFFFF" />
</LinearLayout>
然后就是为选择程度的圆添加我们刚刚在view里面暴露的接口方法
public class ProgressCircleActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress_circle);
final ManualCircle myView = (ManualCircle) findViewById(R.id.myview);
myView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
myView.add();
}
});
final AutomaticCircle automaticCircle=(AutomaticCircle)findViewById(R.id.automaticCircle);
automaticCircle.setScore(80);
}
}
二、用弧度变化表示进度的程度圆
1.先给出view的代码,在代码里面解析
package com.demo.myview.progressCircle;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import com.demo.myview.R;
/**
* Created by ${符柱成} on 2016/8/21.
*/
public class AutomaticCircle extends View {
private int mScore;
private Paint mBlackPaint, mWhitePaint, mCirclePaint, mTextPaint;
/**
* 圆环的宽度
*/
private int mCircleWidth;
private RectF mRectF;
int i = 0;
int count;
private int centerCircleColor;
private int bottomRingColor;
private int drawRingColor;
private int textColor;
public AutomaticCircle(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AutomaticCircleProgress);
int n = typedArray.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.AutomaticCircleProgress_automaticCircleWidth:
mCircleWidth = (int) typedArray.getDimension(attr, 0);
break;
case R.styleable.AutomaticCircleProgress_automaticCentercircleColor:
centerCircleColor = typedArray.getColor(attr, 0);
Log.e("centerColor", String.valueOf(centerCircleColor));
break;
case R.styleable.AutomaticCircleProgress_automaticBottomRingColor:
bottomRingColor = typedArray.getColor(attr, 0);
Log.e("centerColor", String.valueOf(bottomRingColor));
break;
case R.styleable.AutomaticCircleProgress_automaticDrawRingColor:
drawRingColor = typedArray.getColor(attr, 0);
break;
case R.styleable.AutomaticCircleProgress_automaticTextColor:
textColor = typedArray.getColor(attr, 0);
break;
}
}
initPaint();
}
private void initPaint() {
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setDither(true);
mCirclePaint.setColor(centerCircleColor);
mBlackPaint = new Paint();
mBlackPaint.setAntiAlias(true);
mBlackPaint.setDither(true);
mBlackPaint.setColor(bottomRingColor);
mBlackPaint.setStyle(Paint.Style.STROKE);
mBlackPaint.setStrokeWidth(mCircleWidth);
mWhitePaint = new Paint();
mWhitePaint.setAntiAlias(true);
mWhitePaint.setStyle(Paint.Style.STROKE);
mWhitePaint.setStrokeWidth(mCircleWidth);
mWhitePaint.setDither(true);
mWhitePaint.setColor(drawRingColor);
mTextPaint = new Paint();
mTextPaint.setTextSize(40);
mTextPaint.setDither(true);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setColor(textColor);
this.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
new DrawThread();
getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float xy = getWidth() / 2;
float radius = xy - mCircleWidth;
mRectF = new RectF();
mRectF.set(xy - radius - mCircleWidth / 2, xy - radius - mCircleWidth / 2, xy + radius + mCircleWidth / 2, xy + radius + mCircleWidth / 2);
canvas.drawCircle(xy, xy, radius, mCirclePaint);
canvas.drawArc(mRectF, 0, 360, false, mBlackPaint);
canvas.drawArc(mRectF, -90, i, false, mWhitePaint);
canvas.drawText(count + "", xy, xy, mTextPaint);
}
public void setScore(int score) {
this.mScore = score;
}
public class DrawThread implements Runnable {
private final Thread mDrawThread;
private int statek;
public DrawThread() {
mDrawThread = new Thread(this);
mDrawThread.start();
}
@Override
public void run() {
while (true) {
switch (statek) {
case 0:
try {
Thread.sleep(200);
statek = 1;
} catch (InterruptedException e) {
}
break;
case 1:
try {
Thread.sleep(20);
i += 3.6f;
count++;
postInvalidate();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
if (count >= mScore)
break;
}
}
}
}
恩,属性文件和调用的代码都在上一个例子里面了,这里就不再贴了。
好了,自定义view圆已经讲解完毕,欢迎指出错误,共同学习。接下来一段时间还会更新一系列的自定义view,敬请关注。
转载请注明:【JackFrost的博客】