Android——Canvas(画布)的使用

来源:互联网 发布:淘宝电脑端描述怎么写 编辑:程序博客网 时间:2024/06/05 20:06

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;        }    }}
0 0