概述:
利用自定义View的onDraw()方法,可以绘制很多种图形,进度框只是其中之一。
Demo
这是一个模拟下载的demo。
自中央逐渐充满型圆形进度框
demo1
public class FirstProgressView extends View{
private int width;
private int height;
private int progress;
private int maxProgress = 100;
private Paint mPaintBackGround;
private Paint mPaintCurrent;
private Paint mPaintText;
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
invalidate();
}
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public FirstProgressView(Context context) {
super(context);
}
public FirstProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintBackGround = new Paint();//新定义一个画笔,用来画背景
mPaintBackGround.setColor(Color.GRAY);//设置画笔颜色
mPaintBackGround.setAntiAlias(true);//设置为true,代表抗锯齿
mPaintCurrent = new Paint();//用于画进度图
mPaintCurrent.setColor(Color.GREEN);
mPaintCurrent.setAntiAlias(true);
mPaintText = new Paint();//用来画文本的画笔
mPaintText.setColor(Color.BLACK);
mPaintText.setAntiAlias(true);
mPaintText.setTextAlign(Paint.Align.CENTER);//设置文本排布方式:正中央
mPaintText.setTextSize(50);//设置文本大小,这里为50xp
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//左起:圆心x座标,圆心y座标,半径,Paint对象(画笔)
canvas.drawCircle(width / 2, height / 2, 400, mPaintBackGround);
canvas.drawCircle(width/2,height/2,progress*400f/maxProgress,mPaintCurrent);
//左起:文本内容,起始位置x座标,起始位置y座标,画笔
canvas.drawText(progress*100f/maxProgress+"%",width / 2, height / 2,mPaintText);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//该View布局宽
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
//该View布局高
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
//设定本View的大小的方法
setMeasuredDimension(width, height);
}
}
水箱型注水式进度框
demo2
public class SecondProgressView extends View {
private int width;
private int height;
private int progress;
private int maxProgress = 100;
private Paint mPaintBackGround;
private Paint mPaintCurrent;
private Paint mPaintText;
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
invalidate();
}
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public SecondProgressView(Context context) {
super(context);
}
public SecondProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintBackGround = new Paint();
mPaintBackGround.setColor(Color.GRAY);
mPaintBackGround.setStyle(Paint.Style.STROKE);
mPaintBackGround.setStrokeWidth(20);
mPaintBackGround.setAntiAlias(true);
mPaintCurrent = new Paint();
mPaintCurrent.setColor(Color.BLUE);
mPaintCurrent.setAntiAlias(true);
mPaintText = new Paint();
mPaintText.setColor(Color.BLACK);
mPaintText.setAntiAlias(true);
mPaintText.setTextAlign(Paint.Align.CENTER);
mPaintText.setTextSize(50);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(width / 2 - 200, height / 2 - 200, width / 2 + 200, height / 2 + 200, mPaintBackGround);
canvas.drawRect(width/2-190,height/2-190+(380-progress*380f/maxProgress),width/2+190,height/2+190,mPaintCurrent);
canvas.drawText(progress*100f/maxProgress+"%",width / 2, height / 2,mPaintText);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}
}
圆圈式弧形进度框:
demo3:
public class ThirdProgressView extends View {
private int width;
private int height;
private int progress;
private int maxProgress = 100;
private Paint mPaintBackGround;
private Paint mPaintCurrent;
private Paint mPaintText;
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
invalidate();
}
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public ThirdProgressView(Context context) {
super(context);
}
public ThirdProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintBackGround = new Paint();
mPaintBackGround.setColor(Color.GRAY);
mPaintBackGround.setStrokeWidth(60);
mPaintBackGround.setStyle(Paint.Style.STROKE);
mPaintBackGround.setAntiAlias(true);
mPaintCurrent = new Paint();
mPaintCurrent.setColor(Color.GREEN);
mPaintCurrent.setStrokeWidth(60);
mPaintCurrent.setStyle(Paint.Style.STROKE);
mPaintCurrent.setAntiAlias(true);
mPaintText = new Paint();
mPaintText.setColor(Color.BLACK);
mPaintText.setAntiAlias(true);
mPaintText.setTextAlign(Paint.Align.CENTER);
mPaintText.setTextSize(50);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(width / 2, height / 2, 400, mPaintBackGround);
RectF oval = new RectF(width/2-400,height/2-400,width/2+400,height/2+400);
//左起分别是RectF对象,起始角度,终止角度,是否显示扇边(如果为true画出的是一个扇形),Paint对象
canvas.drawArc(oval,0,progress*360f/maxProgress,false,mPaintCurrent);
canvas.drawText(progress*100f/maxProgress+"%",width / 2, height / 2,mPaintText);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}
}
需要在布局文件中加载自定义View,这里随便加载一个作示范(自定义View都这么加载):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Download"/>
<com.example.administrator.selfdefinedview.widget.ThirdProgressView
android:id="@+id/progress_view_first"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
主活动的中自定义View也需要声明和findViewById,这里写的是一个模拟下载的小demo,加载的是第三种自定义View,其他的自定义View加载方式完全一样。
public class MainActivity extends Activity {
private int progress;
private Button mButtonStart;
private ThirdProgressView mProgressView;
private static final int DOWNLOAD_UPDATE = 0x99;
//模拟下载
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//处理msg
switch (msg.what) {
case DOWNLOAD_UPDATE:
progress++;
if (progress <= 100) {
mProgressView.setProgress(progress);
sendEmptyMessageDelayed(DOWNLOAD_UPDATE, 100);//每隔100毫秒发送一次handler
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButtonStart = (Button) findViewById(R.id.button_start);
mProgressView = (ThirdProgressView) findViewById(R.id.progress_view_first);
mButtonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//向handler发送一个延时空消息,1000毫秒后发送
mHandler.sendEmptyMessageDelayed(DOWNLOAD_UPDATE, 1000);
}
});
}
}
我们猿类工作压力大,很需要有自己的乐趣,于是乎,我开通了音乐人账号,以后的作品将会上传到我的音乐人小站上。如果这篇博客帮助到您,希望您能多关注,支持,鼓励我将创作进行下去,同时也祝你能在工作和生活乐趣两发面都能出彩!