Canvas的一些基本方法:
Canvas():创建一个空的画布,可以使用setBitmap()方法来设置绘制的具体画布;
Canvas(Bitmap bitmap):以bitmap对象创建一个画布,则将内容都绘制在bitmap上,bitmap不得为null;
Canvas(GL gl):在绘制3D效果时使用,与OpenGL有关;
drawColor:设置画布的背景色;
setBitmap:设置具体的画布;
clipRect:设置显示区域,即设置裁剪区;
isOpaque:检测是否支持透明;
rotate:旋转画布;
canvas.drawRect(RectF,Paint)方法用于画矩形,第一个参数为图形显示区域,第二个参数为画笔,设置好图形显示区域Rect和画笔Paint后,即可画图;
canvas.drawRoundRect(RectF, float, float, Paint) 方法用于画圆角矩形,第一个参数为图形显示区域,第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。
canvas.drawLine(startX, startY, stopX, stopY, paint):前四个参数的类型均为float,最后一个参数类型为Paint。表示用画笔paint从点(startX,startY)到点(stopX,stopY)画一条直线;
canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint):第一个参数oval为RectF类型,即圆弧显示区域,startAngle和sweepAngle均为float类型,分别表示圆弧起始角度和圆弧度数,3点钟方向为0度,useCenter设置是否显示圆心,boolean类型,paint为画笔;
canvas.drawCircle(float,float, float, Paint)方法用于画圆,前两个参数代表圆心坐标,第三个参数为圆半径,第四个参数是画笔;
Rect(int left,int top,int right,int bottom)
left
矩形左上角X坐标值
top
矩形左上角Y坐标值
right
矩形右下角X坐标值
bottom
矩形右下角Y坐标值
画布的一般使用步骤:
创建一个自定义View 让他继承View,并创建他的两个构造器,并:
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) { super(context, attrs);}
重写里面的onMeasure和onDraw方法,并在onMeasure方法中,得到自定义View的宽高:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);//宽
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);//高
setMeasuredDimension(width, height);//设置得到的宽高
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
在布局文件中设置刚创建自定义View:
<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<com.example.administrator.myviewdemo.widget.ProgressBarCircle//自定义View
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
开始绘画,在构造器中创建一个新的画笔对象,并对其进行属性设置,然后在onDraw方法里运用Canvas的方法绘画即可。
实例
1.画一个时钟
布局文件
<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<com.example.administrator.myviewdemo.widget.ProgressBarCircle
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
自定义View
package com.example.administrator.myviewdemo.widget;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import java.util.Calendar;
/**
* Created by Administrator on 2015/9/16.
* 画一个时钟
*/
public class MyView extends View {
private int width;
private int height;
private Paint mPaintLine;
private Paint mPaintCircle;
private Paint mPaintText;
private Calendar mCalendar;
private static final int NEED_INVALIDATE = 0x23;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case NEED_INVALIDATE:
mCalendar = Calendar.getInstance();//得到当前时间
invalidate();//告诉主线程重新绘制
handler.sendEmptyMessageDelayed(NEED_INVALIDATE, 1000);//1秒钟发送一次空消息
break;
}
}
};
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintText = new Paint();//对画笔初始化
mPaintText.setTextSize(30);//设置字体大小
mPaintText.setColor(Color.BLACK);//设置画笔颜色
mPaintText.setTextAlign(Paint.Align.CENTER);//设置文本对齐方式
mPaintLine = new Paint();
mPaintLine.setColor(Color.RED);
mPaintLine.setStrokeWidth(10);//设置画笔宽度
mPaintLine.setAntiAlias(true);
mPaintCircle = new Paint();
mPaintCircle.setColor(Color.GREEN);
mPaintCircle.setStyle(Paint.Style.STROKE);//设置为空心的
mPaintCircle.setStrokeWidth(10);
mPaintLine.setAntiAlias(true);//设置抗锯齿
mCalendar = Calendar.getInstance();
handler.sendEmptyMessage(NEED_INVALIDATE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//由主线程自动调用,只需在此绘制即可
canvas.drawCircle(width / 2, height / 2, 180, mPaintCircle);
canvas.drawCircle(width / 2, height / 2, 5, mPaintCircle);
for (int i = 1; i <= 12; i++) {
canvas.save();
canvas.rotate(30 * i, width / 2, height / 2);
canvas.drawText("" + i, width / 2, height / 2 - 140, mPaintText);
canvas.drawLine(width / 2, height / 2 - 180, width / 2, height / 2 - 160, mPaintLine);
canvas.restore();
}
//得到小时数、分钟数、秒数
int minute = mCalendar.get(Calendar.MINUTE);
int hour = mCalendar.get(Calendar.HOUR);
int second = mCalendar.get(Calendar.SECOND);
float degree = minute / 60f * 360;
canvas.save();
canvas.rotate(degree, width / 2, height / 2);
canvas.drawLine(width / 2, height / 2 - 120, width / 2, height / 2 + 10, mPaintLine);//画分针
canvas.restore();
float hourDegree = (hour * 60 + minute) / (12f * 60) * 360;
canvas.save();
canvas.rotate(hourDegree, width / 2, height / 2);
canvas.drawLine(width / 2, height / 2 - 100, width / 2, height / 2 + 5, mPaintLine);//画时针
canvas.restore();
canvas.save();
canvas.rotate(second * 6, width / 2, height / 2);//每秒旋转6度
canvas.drawLine(width / 2, height / 2 - 140, width / 2, height / 2 + 15, mPaintLine);//画秒针
canvas.restore();
}
}
MainActivity
package com.example.administrator.myviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
2.Progressbar(1)
package com.example.administrator.myviewdemo.widget;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Administrator on 2015/9/16.
*/
public class ProgressBarCircle extends View {
private int maxProgress=100;
private int currentProgress;
private int width;
private int height;
private Paint mPaintProgressMax;
private Paint mPaintProgressCurrent;
private static final int UPDATA_PROGRESS=0x28;
private Paint mPaintText;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case UPDATA_PROGRESS:
if(currentProgress<100) {
currentProgress++;
}
invalidate();
handler.sendEmptyMessageDelayed(UPDATA_PROGRESS,500);
break;
}
}
};
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public int getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(int currentProgress) {
this.currentProgress = currentProgress;
}
public ProgressBarCircle(Context context) {
super(context);
}
public ProgressBarCircle(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintProgressMax=new Paint();
mPaintProgressMax.setColor(Color.GRAY);
mPaintProgressMax.setAntiAlias(true);
mPaintProgressCurrent=new Paint();
mPaintProgressCurrent.setColor(Color.GREEN);
mPaintProgressCurrent.setAntiAlias(true);
mPaintText=new Paint();
mPaintText.setTextSize(100);
mPaintText.setColor(Color.RED);
mPaintText.setTextAlign(Paint.Align.CENTER);
handler.sendEmptyMessage(UPDATA_PROGRESS);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(width/2,height/2,200,mPaintProgressMax);
canvas.drawCircle(width/2,height/2,currentProgress*200f/maxProgress,mPaintProgressCurrent);
canvas.drawText(currentProgress*100f/maxProgress+"%",width/2,height/2,mPaintText);
}
}
2.Progressbar(2)
自定义View
package com.example.administrator.myprogressbar2.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Administrator on 2015/9/16.
*/
public class MyProgressBar extends View {
private int width;
private int height;
private int maxProgress=100;
private float currentProgress;
private Paint mPaintrectangleMax;
private Paint mPaintrectangleCurrent;
private Paint mPaintText;
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public float getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(float currentProgress) {
this.currentProgress = currentProgress;
invalidate();
}
public MyProgressBar(Context context) {
super(context);
}
public MyProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintrectangleMax=new Paint();
mPaintrectangleMax.setColor(Color.BLACK);
mPaintrectangleMax.setStyle(Paint.Style.STROKE);
mPaintrectangleMax.setTextAlign(Paint.Align.CENTER);
mPaintrectangleCurrent=new Paint();
mPaintrectangleCurrent.setColor(Color.GREEN);
mPaintText=new Paint();
mPaintText.setColor(Color.BLACK);
mPaintText.setTextSize(50);
mPaintText.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(60, 90, 180, 300, mPaintrectangleMax);// (60,90)长方形左上顶点。(180,300)右下顶点
// canvas.drawLine(60,300-currentProgress*210f/maxProgress,180,300-currentProgress*210f/maxProgress,mPaintrectangleCurrent);
canvas.drawRect(60,300-currentProgress*210/maxProgress,180,300,mPaintrectangleCurrent);
canvas.drawText(currentProgress+"%",150,240,mPaintText);
}
}
布局文件
<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:id="@+id/btn_startdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始下载"/>
<com.example.administrator.myprogressbar2.widget.MyProgressBar
android:id="@+id/progressbar2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
MainActivity
package com.example.administrator.myprogressbar2;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import com.example.administrator.myprogressbar2.widget.MyProgressBar;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button mBtnStartDown;
private MyProgressBar myProgressBar;
private int progress;
private static final int UPDATA_PROGRESS=0x44;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case UPDATA_PROGRESS:
if(progress<100){
progress++;
}
myProgressBar.setCurrentProgress(progress);
handler.sendEmptyMessageDelayed(UPDATA_PROGRESS,300);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtnStartDown= (Button) findViewById(R.id.btn_startdown);
mBtnStartDown.setOnClickListener(this);
myProgressBar= (MyProgressBar) findViewById(R.id.progressbar2);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_startdown:
handler.sendEmptyMessage(UPDATA_PROGRESS);
break;
}
}
}
Progressbar(3)
自定义View
package com.example.administrator.myprogressbararc.widget;
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 ProgressbarArc extends View {
private int width;
private int height;
private float a=1.1111f;
private int maxProgress=100;
private float currentProgress;
private Paint mPaintrectangleMax;
private Paint mPaintrectangleCurrent;
private Paint mPaintText;
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public double getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(float currentProgress) {
this.currentProgress = currentProgress;
invalidate();
}
public ProgressbarArc(Context context) {
super(context);
}
public ProgressbarArc(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintrectangleMax=new Paint();
mPaintrectangleMax.setColor(Color.BLUE);
mPaintrectangleMax.setAntiAlias(true);
mPaintrectangleMax.setTextAlign(Paint.Align.CENTER);
mPaintrectangleCurrent=new Paint();
mPaintrectangleCurrent.setColor(Color.GREEN);
mPaintrectangleCurrent.setStrokeWidth(20);
mPaintrectangleCurrent.setStyle(Paint.Style.STROKE);
mPaintrectangleCurrent.setAntiAlias(true);
mPaintText=new Paint();
mPaintText.setColor(Color.BLACK);
mPaintText.setTextSize(50);
mPaintText.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF rectF=new RectF(90,90,300,300);
RectF rectF1=new RectF(100,100,290,290);
canvas.drawArc(rectF,0,360,false,mPaintrectangleMax);
canvas.drawArc(rectF1,0,currentProgress*360f/maxProgress,false,mPaintrectangleCurrent);
canvas.drawText((float)Math.round(currentProgress*10000/maxProgress)/100+"%",195,195,mPaintText);
}
}
布局文件代码就不上了,MainActivity中
package com.example.administrator.myprogressbararc;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import com.example.administrator.myprogressbararc.widget.ProgressbarArc;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button mBtnStartDown;
private ProgressbarArc myProgressBar;
private float progress;
private static final int UPDATA_PROGRESS=0x44;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case UPDATA_PROGRESS:
if(progress<100){
progress+=0.25;
}
myProgressBar.setCurrentProgress(progress);
handler.sendEmptyMessageDelayed(UPDATA_PROGRESS,100);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtnStartDown= (Button) findViewById(R.id.btn_progressbar_arc);
mBtnStartDown.setOnClickListener(this);
myProgressBar= (ProgressbarArc) findViewById(R.id.progressbararc);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_progressbar_arc:
handler.sendEmptyMessage(UPDATA_PROGRESS);
break;
}
}
}