自定义控件之_自定义圆形进度条

42 篇文章 1 订阅
28 篇文章 0 订阅

    自定义一个圆形的进度条,先看看效果,虽然很丑,可是都是自己 的心血啊,哈哈



    下面来总结一下步骤:    
---------------------------------------------------------------------------------------------------------------------
第一步:创建一个类继承View或者View的子类
第二步:重写构造方法(初始化一些必要的属性)
  
  
public viewContext context //当在代码中创建对象时会被调用
public View (Context context, AttributeSet attrs)//在布局文件声明时调用
public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)(api>=5.0)
public View (Context context, AttributeSet attrsint defStyle) api>=3.0(在布局文件中加入Themestyle中调用)
//参数一:上下文
//参数二:AttributeSet布局文件属性
//参数三:style是指它在当前ApplicationActivity所用的Theme中的默认Style
第三步:在res/vaules/attrs.xml中创建自定义属性
第四步:重写onDraw()方法
第五步:重写onMesure (测量的高度和宽度非必要)
第六步:使用在布局文件中采(用包名+类名)的方式声明
总结
如果需要改变View绘制的图像,那么需要重写OnDraw方法。(这也是最常用的重写方式。)
如果需要改变view的大小,那么需要重写OnMeasure方法。
如果需要改变View的(在父控件的)位置,那么需要重写OnLayout方法
---------------------------------------------------------------------------------------------------------------------
    所以先上自定义工具类--CircleProgressBar.java
    我们在构造方法中通过 TypedArray 拿到我们定义的自定义控件的属性,在onDraw()方法中讲得到的属性值应用到我们的控件中,比如我们可以拿到调用者调用该控件时设置的外面大圈的颜色值----- circleBackColor = array . getColor ( R . styleable . CircleProgressBar_circleBackColor , Color . GREEN ); 当然,默认值是绿色,然后在onDraw方法中,
    //给外圈设置颜色
    paint.setColor(circleBackColor);
     在画外圈的时候,我们先给画笔设置颜色。再画圈。
     当然 ,在这个工具类(自定义控件)中,我们还要提供一些方法来操纵我们的控件,比如就拿这个HelloWorld级别的自定义进度条 来说,他的一个必须的功能就是对外提供让调用者可以设置当前进度的方法,在这里,这个方法叫 setProgress()
     下面,我们来看下这个方法的具体实现
    public synchronized void setProgress(int progress) {
if(progress>maxProgress){
currentProgress=maxProgress;
}else{
this.currentProgress = progress;
postInvalidate();
}
}
  简单的说明一下,在设置进度的时候,该控件为线程安全的控件,要考虑到多线程的问题,所以需要线程同步。刷新界面的时候,也要 调用   postInvalidate(), 这样才能在非UI线程也可以刷新!
   
   
package com.example.ycdyus.day26.view;
 
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;
 
import com.example.ycdyus.day26.R;
 
/**
* Created by ycdyus on 2015/9/29.
*/
public class CircleProgressBar extends View {
private Paint paint;
private int minProgress = 0;
private int maxProgress = 100;
private int currentProgress = 0;
private int textColor;
private int textSize;
private int circleBackColor;
private int circleProColor;
private int strokeWidth;
private int circleStyle=0;
private int textStyle=1;
private float circleRadius;
 
 
public CircleProgressBar(Context context) {
this(context,null);
}
 
public CircleProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
 
public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
 
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
paint = new Paint();
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);
textColor = array.getColor(R.styleable.CircleProgressBar_circleTextColor, Color.BLACK);
textSize = array.getDimensionPixelOffset(R.styleable.CircleProgressBar_circleTextSize, 18);
circleBackColor=array.getColor(R.styleable.CircleProgressBar_circleBackColor, Color.GREEN);
circleProColor=array.getColor(R.styleable.CircleProgressBar_circleProColor, Color.RED);
strokeWidth = array.getInt(R.styleable.CircleProgressBar_circleStrokeWidth, 10);
circleStyle = array.getInteger(R.styleable.CircleProgressBar_circleStrokeType, 0);
textStyle = array.getInteger(R.styleable.CircleProgressBar_textStrokeType, 1);
circleRadius = array.getFloat(R.styleable.CircleProgressBar_circleRadius,200);
array.recycle();
}
 
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//计算当前进度百分比
int currentPro=(currentProgress>maxProgress)?100:((currentProgress*100/maxProgress));
//获取圆心的x坐标
int centre = getWidth()/2;
//圆环的半径
int radius = centre - strokeWidth;
//消除锯齿
paint.setAntiAlias(true);
//给外圈设置样式
paint.setStyle(circleStyle == 0 ? Paint.Style.STROKE : Paint.Style.FILL);
//设置StrokeWidth
paint.setStrokeWidth(strokeWidth);
//给外圈设置颜色
paint.setColor(circleBackColor);
//画最外层的圈
canvas.drawCircle(centre, centre, radius, paint);
//设置进度的颜色
paint.setColor(circleProColor);
//定义一个RectF类
RectF rectF = new RectF(centre-radius,centre-radius,centre+radius,centre+radius);
//绘制扇形
canvas.drawArc(rectF,270,(int)(currentPro*3.6),false,paint);
//设置进度扇形的颜色
paint.setColor(textColor);
//设置进度扇形的样式
paint.setStyle(textStyle == 0 ? Paint.Style.STROKE : Paint.Style.FILL);
//设置文字的大小
paint.setTextSize(textSize);
//计算进度
int width = (int) paint.measureText(currentPro+"%");
//绘制文字
canvas.drawText(currentPro+"%", centre-width/2, centre+textSize/4, paint);
}
 
public int getMaxProgress() {
return maxProgress;
}
 
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
 
public int getMinProgress() {
return minProgress;
}
 
public void setMinProgress(int minProgress) {
this.minProgress = minProgress;
}
 
public synchronized void setProgress(int progress) {
if(progress>maxProgress){
currentProgress=maxProgress;
}else{
this.currentProgress = progress;
postInvalidate();
}
 
}
 
public int getCircleBackColor() {
return circleBackColor;
}
 
public void setCircleBackColor(int circleBackColor) {
this.circleBackColor = circleBackColor;
}
 
public int getCircleProColor() {
return circleProColor;
}
 
public void setCircleProColor(int circleProColor) {
this.circleProColor = circleProColor;
}
 
public float getCircleRadius() {
return circleRadius;
}
 
public void setCircleRadius(float circleRadius) {
this.circleRadius = circleRadius;
}
 
public int getCircleStyle() {
return circleStyle;
}
 
public void setCircleStyle(int circleStyle) {
this.circleStyle = circleStyle;
}
 
public int getCurrentProgress() {
return currentProgress;
}
 
public void setCurrentProgress(int currentProgress) {
this.currentProgress = currentProgress;
}
 
public int getStrokeWidth() {
return strokeWidth;
}
 
public void setStrokeWidth(int strokeWidth) {
this.strokeWidth = strokeWidth;
}
 
public int getTextColor() {
return textColor;
}
 
public void setTextColor(int textColor) {
this.textColor = textColor;
}
 
public int getTextSize() {
return textSize;
}
 
public void setTextSize(int textSize) {
this.textSize = textSize;
}
 
public int getTextStyle() {
return textStyle;
}
 
public void setTextStyle(int textStyle) {
this.textStyle = textStyle;
}
}
    下面再贴出属性文件attrs.xml,在使用的时候,要将该文件放在values文件夹下。
    下面就属性说下,比如之前说的, circleBackColor 属性,该属性是设置颜色的,所以 format = "color"
   
   
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgressBar">
<attr name="circleTextSize" format="dimension"></attr>
<attr name="circleTextColor" format="color"></attr>
<attr name="circleBackColor" format="color"></attr>
<attr name="circleProColor" format="color"></attr>
<attr name="circleStrokeWidth" format="integer"></attr>
<attr name="circleRadius" format="float"></attr>
<attr name="circleStrokeType">
<enum name="STROKE" value="0"></enum>
<enum name="FILL" value="1"></enum>
</attr>
<attr name="textStrokeType">
<enum name="STROKE" value="0"></enum>
<enum name="FILL" value="1"></enum>
</attr>
</declare-styleable>
</resources>
    那么 这些工作 都准备好了之后,如何才能调用呢???很简单,直接在布局文件中调用即可!----  activity_secnd.xml
   
   
<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"
tools:context="com.example.ycdyus.day26.SecndActivity">
 
<com.example.ycdyus.day26.view.CircleProgressBar
android:id="@+id/id_circleprogressbar"
app:circleTextSize="20sp"
app:circleTextColor="@color/highlighted_text_material_dark"
android:layout_width="200dp"
android:layout_margin="30dp"
android:layout_height="200dp" />
 
</RelativeLayout>
    最后贴出Activity的源码,------ SecndActivity.java
  
  
package com.example.ycdyus.day26;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
 
import com.example.ycdyus.day26.view.CircleProgressBar;
 
public class SecndActivity extends AppCompatActivity {
private CircleProgressBar circleProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_secnd);
initView();
}
 
private void initView() {
circleProgressBar = (CircleProgressBar) findViewById(R.id.id_circleprogressbar);
new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(i<=100){
try {
circleProgressBar.setProgress(i);
Thread.sleep(100);
Log.i("HHHH",i+"");
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
 
}
转载请注明出处。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值