主函数
这几种进度条的主函数都是类似的,所以下面我只给出了一个填充型进度条的主函数,其他几个主函数只是在这基础上改动一下按钮id(即与各自布局里面的id相同即可),还有改动一下相对应的类即可。
public class MainActivity extends AppCompatActivity {
private Button mButtonStart;
private MyProgress myProgress;
private int progress;
private static final int PROGRESS=0X23;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case PROGRESS:
progress++;
if (progress<=100){
myProgress.setCurrentProgress(progress);
handler.sendEmptyMessageDelayed(PROGRESS,200);
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButtonStart= (Button) findViewById(R.id.button_start);
myProgress= (MyProgress) findViewById(R.id.myprogress);
mButtonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.sendEmptyMessageDelayed(PROGRESS,1000);
}
});
}
}
矩形进度条自定义View
public class Rectangle extends View {
private int mProgress;
private Paint mCurrentProgress;
private Paint mMaxProgress;
private Paint mPaintText;
private int mWidth;
private int mHeight;
public Rectangle(Context context) {
super(context);
}
public Rectangle(Context context, AttributeSet attrs) {
super(context, attrs);
mCurrentProgress = new Paint();
mCurrentProgress.setColor(Color.YELLOW);
mCurrentProgress.setAntiAlias(true);
mMaxProgress = new Paint();
mMaxProgress.setColor(Color.WHITE);
mMaxProgress.setAntiAlias(true);
mPaintText = new Paint();
mPaintText.setColor(Color.RED);
mPaintText.setStrokeWidth(5);
mPaintText.setAntiAlias(true);
mPaintText.setTextSize(100);
mPaintText.setTextAlign(Paint.Align.CENTER);
}
public int getmProgress() {
return mProgress;
}
public void setmProgress(int mProgress) {
this.mProgress = mProgress;
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth=getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mHeight= getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(mWidth / 2-160, mHeight / 2-250,mWidth / 2+160, mHeight / 2+250, mMaxProgress);
canvas.drawRect(mWidth / 2-160, mHeight / 2+250-(mProgress/100f*500),mWidth / 2+160, mHeight / 2+250, mCurrentProgress);
canvas.drawText(mProgress+"%", mWidth / 2, mHeight / 2, mPaintText);
}
}
矩形进度条的布局
<Button
android:id="@+id/button_round"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始下载"/>
<com.example.administrator.definedviewdemo.Wiget.Rectangle
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rectangle"/>
成像图
圆环形进度条自定义View
import android.content.Context;
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 Administrator on 2015/9/16.
*/
public class RoundProgressBar extends View {
private Paint mPaintBackCircle;
private Paint mPaintInfrontCircle;
private int currentProgress;
private int mwidth;
private int mheight;
private Paint mPaintText;
private RectF mOval;
public int getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(int currentProgress) {
this.currentProgress = currentProgress;
invalidate();//告诉UI线程重新绘制
}
public RoundProgressBar(Context context) {
super(context);
}
public RoundProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintBackCircle=new Paint();
mPaintBackCircle.setColor(Color.GRAY);
mPaintBackCircle.setStrokeWidth(1);
mPaintBackCircle.setAntiAlias(true);
mPaintBackCircle.setStyle(Paint.Style.STROKE);
mPaintInfrontCircle=new Paint();
mPaintInfrontCircle.setColor(Color.GREEN);
//这里的宽度是画填充圆环时的宽度,即两个圆的半径之差。
mPaintInfrontCircle.setStrokeWidth(40);
mPaintInfrontCircle.setAntiAlias(true);
mPaintInfrontCircle.setStyle(Paint.Style.STROKE);
mPaintText=new Paint();
mPaintText.setColor(Color.RED);
mPaintText.setTextSize(50);
mPaintText.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mwidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mheight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mwidth/2, mheight/2,200,mPaintBackCircle);
canvas.drawCircle(mwidth/2, mheight/2,160,mPaintBackCircle);
// 设置个新的长方形,扫描测量,减去的值为两个半径的中间值
RectF oval1=new RectF(mwidth / 2-180, mheight / 2-180,mwidth / 2+180, mheight / 2+180);
// 画弧,第一个参数是RectF:该类是第二个参数是角度的开始,第三个参数是多少度,第四个参数是真的时候画扇形,是假的时候画弧线
canvas.drawArc( oval1, 0,currentProgress/100f*360 ,false, mPaintInfrontCircle);
canvas.drawText(currentProgress+"%",mwidth/2,mheight/2,mPaintText);
}
}
圆环形进度条的布局
<Button
android:id="@+id/button_round"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始下载"/>
<com.example.administrator.definedviewdemo.Wiget.RoundProgressBar
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/round"/>
成像图
填充型进度条自定义View
public class MyProgress extends View {
private int mWidth;
private int mHeight;
private Paint mPaintBackGround;
private Paint mPaintCurrent;
private Paint mPaintText;
private int currentProgress;
public int getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(int currentProgress) {
this.currentProgress = currentProgress;
invalidate();//告诉UI线程重新绘制
}
public MyProgress(Context context) {
super(context);
}
public MyProgress(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintBackGround = new Paint();
mPaintBackGround.setAntiAlias(true);
mPaintBackGround.setColor(Color.GRAY);
mPaintCurrent = new Paint();
mPaintCurrent.setAntiAlias(true);
mPaintCurrent.setColor(Color.GREEN);
mPaintText = new Paint();
mPaintText.setAntiAlias(true);
mPaintText.setColor(Color.BLACK);
mPaintText.setTextSize(100);
mPaintText.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mWidth / 2, mHeight / 2, 200, mPaintBackGround);
canvas.drawCircle(mWidth / 2, mHeight / 2, 200/100f*currentProgress,mPaintCurrent);
canvas.drawText(currentProgress+"%", mWidth / 2, mHeight / 2, mPaintText);
}
}
填充型进度条布局
<Button
android:id="@+id/button_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始下载"/>
<com.example.administrator.definedviewdemo.Wiget.MyProgress
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/myprogress"/>
成像图
时钟自定义View
public class MyView extends View {
private int mWidth;
private int mHeight;
private Paint mPaint;
private Paint mPaintMinute;
private Paint mPaintHour;
private Paint mPaintCircle;
private Paint mPaintText;
private Calendar mCalendar;
private static final int NEED_UPDATE=34;
private Handler mHandler=new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case NEED_UPDATE:
mCalendar=Calendar.getInstance();
invalidate();
mHandler.sendEmptyMessageDelayed(NEED_UPDATE, 1000);
break;
default:
break;
}
};
};
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mCalendar=Calendar.getInstance();
//查看api以了解它的具体使用方法(canvas View的api)
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(5);
mPaint.setAntiAlias(true);
mPaintHour = new Paint();
mPaintHour.setColor(Color.BLACK);
mPaintHour.setStrokeWidth(5);
mPaintHour.setAntiAlias(true);
mPaintMinute = new Paint();
mPaintMinute.setColor(Color.GREEN);
mPaintMinute.setStrokeWidth(5);
mPaintMinute.setAntiAlias(true);
mPaintCircle = new Paint();
mPaintCircle.setColor(Color.BLUE);
mPaintCircle.setStrokeWidth(5);
mPaintCircle.setAntiAlias(true);
mPaintCircle.setStyle(Paint.Style.STROKE);
mPaintText = new Paint();
mPaintText.setColor(Color.DKGRAY);
mPaintText.setTextSize(30);
mPaintText.setTextAlign(Paint.Align.CENTER);
mPaintText.setStrokeWidth(5);
mPaintText.setAntiAlias(true);
mHandler.sendEmptyMessageDelayed(NEED_UPDATE, 1000);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
{
super.onDraw(canvas);
// 传入像素值,查看api
//画出表盘
canvas.drawCircle(mWidth / 2, mHeight / 2, 300, mPaintCircle);
canvas.drawCircle(mWidth / 2, mHeight / 2, 10, mPaintCircle);
for (int i = 1; i <= 12; i++) {
//保存画布此时的状态
canvas.save();
canvas.rotate(360 / 12 * i, mWidth / 2, mHeight / 2);
canvas.drawLine(mWidth / 2, mHeight / 2 - 300, mWidth / 2 - 1, mHeight / 2 - 280, mPaint);
canvas.drawText("" + i, mWidth / 2, mHeight / 2 - 240, mPaintText);
//配合save()使用
canvas.restore();
}
//画出时钟的分针
int minute=mCalendar.get(Calendar.MINUTE);
int hour=mCalendar.get(Calendar.HOUR);
float degreeMinute=minute/60f*360;
canvas.save();
canvas.rotate(degreeMinute,mWidth / 2, mHeight / 2);
canvas.drawLine(mWidth / 2, mHeight / 2-200, mWidth / 2, mHeight / 2+18, mPaintMinute);
canvas.restore();
//画出时钟的时针,计算时针的位置,因为时针一天走两圈,所以除以720,在乘以角度360
float degreeHour=(hour*60+minute)/12f/60*360;
canvas.save();
canvas.rotate(degreeHour,mWidth / 2, mHeight / 2);
canvas.drawLine(mWidth / 2, mHeight / 2-150, mWidth / 2, mHeight / 2+14, mPaintHour);
canvas.restore();
}
//画出秒针
int seconde=mCalendar.get(Calendar.SECOND);
float degreeSeconde=seconde*6;
canvas.save();
canvas.rotate(degreeSeconde,mWidth / 2, mHeight / 2);
canvas.drawLine(mWidth / 2, mHeight / 2-250, mWidth / 2, mHeight / 2+24, mPaint);
canvas.restore();
}
}
特别注意:
//画线的时候,起始点的高度和终止点的高度千万不能写错了——即起始点的高度小于终止点的高度,而且起始点离内圆圆心的长度大于终止点到内圆的长度。
canvas.drawLine(mwidth / 2, mheight / 2 -100, mwidth / 2, mheight / 2 +25, mPaintLine);
时钟自定义View布局
<com.example.administrator.definedviewdemo.Wiget.MyView
android:layout_width="match_parent"
android:layout_height="match_parent" />