源码学习—— Demo解析Canvas绘图

来源:互联网 发布:小米笔记本12.5java 编辑:程序博客网 时间:2024/05/18 15:03

 原文链接:http://blog.csdn.net/qibin0506/article/details/48621855

一:复习原作者提到的基础知识:

1、Handler

子线程处理完耗时操作后,通过Message传递数据给Handler,Handler把消息放在主线程队列中,配合主线程更新UI。

Handler有两个作用:  

(1):定时执行Message和Runnalbe 对象 

(2):让一个动作,在不同的线程中执行。 

Tip:

message是放置信息,可以传递一些参数,

Handler获取这些信息并将判度如何处理,

Runnable则是直接给出处理的方法。


2、绘制扇形

在Canvas上绘制扇形的函数:

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//画弧,

参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数二是起始角(度)在电弧的开始,

参数三扫描角(度)开始顺时针测量的,参数四是如果这是真的话,包括椭圆中心的扇形,并关闭它,如果它是假这将是一个弧线,参数五是Paint对象

建议看这下篇http://blog.csdn.net/rhljiayou/article/details/7212620


3、Shader类

用于渲染图像以及几何形状,包括:

BitmapShader主要用来渲染图像

LinearGradient 用来进行梯度渲染

RadialGradient 用来进行环形渲染

SweepGradient 用来进行梯度渲染

ComposeShader则是一个 混合渲染,可以和其它几个子类组合起来使用。 

使用方法:

先构建Shader对象,然后通过Paint的setShader方法设置渲染对象,然后设置渲染对象,然后再绘制时使用这个Paint对象即可。

建议:http://byandby.iteye.com/blog/831011


4、旋转Canvas类

流程:保存现场——>操作——>恢复现场

  canvas.save(); 
  旋转
 canvas.restore();


二:Canvas基础例子、

自定义一个View,在onDraw中绘制简单的形状

public class BasicUsageView extends View {    Paint paint1 = new Paint();    Paint paint2 = new Paint();    Paint paint3 = new Paint();    Paint paint4 = new Paint();    public BasicUsageView(Context context){        super(context);    }    public BasicUsageView(Context context,Attributes attributes){        super(context,null);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        initPaint();        drawLine(canvas);        drawRect(canvas);        drawCircle(canvas);        drawText(canvas);        drawImg(canvas);        drawOval(canvas);        drawPathLine(canvas);        drawArc(canvas);    }    private void drawArc(Canvas canvas){        //350, 900  20 250        RectF oval = new RectF(400,500,600,800);        canvas.drawArc(oval,0,20,true,paint1);        canvas.drawArc(oval,60,100,false,paint3);        Shader mShader = new LinearGradient(0,0,100,100, new int[]{Color.BLUE,Color.GREEN,Color.YELLOW,Color.RED},        null,Shader.TileMode.REPEAT);        paint1.setShader(mShader);        canvas.drawArc(oval,110,160,true,paint1);    }    private void drawPathLine(Canvas canvas){      Path path = new Path();        path.moveTo(30, 900);        path.lineTo(50, 700);        path.lineTo(80, 900);//        path.lineTo(30,900);        path.moveTo(30,900);        path.lineTo(100, 900);        path.lineTo(75, 700);        path.lineTo(80, 900);        path.moveTo(100, 900);        path.lineTo(150, 400);        path.lineTo(180, 700);        path.lineTo(220, 370);        path.lineTo(300, 810);        path.lineTo(350, 900);        path.lineTo(100,900);        path.close();        canvas.drawPath(path,paint4);    }    private void drawOval(Canvas canvas){        RectF f = new RectF(300,300,600,500);        canvas.drawOval(f,paint2);    }    private void drawImg(Canvas canvas){        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.img),20,350,paint1);    }    private void drawText(Canvas canvas){        canvas.drawText("这是字符串",10,260,paint4);    }    private void drawCircle(Canvas canvas){        //150,100        canvas.drawCircle(150,100,50,paint3);        canvas.drawCircle(150,100,30,paint4);    }    private void drawRect(Canvas canvas){        canvas.drawRect(30, 30, 290, 190, paint1);        RectF rectF = new RectF(50,50,260,150);        canvas.drawRoundRect(rectF,20,20,paint2);    }    private void drawLine(Canvas canvas){        canvas.drawLine(10,10,310,10,paint1);        canvas.drawLine(10,215,310,215,paint2);        canvas.drawLine(10,10,10,215,paint3);        canvas.drawLine(310,10,310,215,paint4);    }    private void initPaint(){        paint1.setAntiAlias(true);//抗锯齿效果        paint1.setColor(Color.parseColor("#C0FF3E"));//画笔颜色        paint1.setAlpha(79);        paint1.setStyle(Paint.Style.FILL);//实心的        paint1.setStrokeWidth(12);        paint2.setColor(Color.CYAN);        paint2.setTextSize(50);        paint2.setStyle(Paint.Style.STROKE);//空心的        paint2.setStrokeWidth(5);        paint3.setColor(Color.RED);        paint3.setTextSize(100);        paint3.setStyle(Paint.Style.STROKE);//空心的        paint3.setStrokeWidth(2);        paint3.setAntiAlias(false);        paint4.setColor(Color.DKGRAY);        paint4.setTextSize(40);        paint4.setStyle(Paint.Style.STROKE);//空心的        paint4.setStrokeWidth(3);        paint4.setAntiAlias(true);        paint4.setDither(true);//设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰    }}

效果图:




运用到的知识点有:画线、画圆、画矩形、Path路径绘制、画图、椭圆……都很简单

二:Demo的实现、

实现思路:

重写View:

在构造函数中初始化Paint画笔;

在onMeasure方法中测量屏幕宽度,设置矩形面积范围、为paint设置Shader样式;

在onDraw中绘制,原理也就是不断地改变扇形的角度,从0一直增加到360度再归零。为了显示更加逼真,就将Canvas也跟着扇形的角度旋转。在对画布进行操作时,记住要保存现场和恢复现场;

效果实现上,点击自定义View,对Handler发送一个小小,让它一直更新扇形的角度,调用直接在线程中调用postInvalidate()方法刷新View.

public class MyCanvasView extends View {private static final int MSG_RUN = 1;private Paint mCirclePaint;private Paint mArcPaint;private Paint mLinePaint;private RectF mRectF;private int mSweepAngle;public MyCanvasView(Context context, AttributeSet attrs) {super(context, attrs);mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mCirclePaint.setColor(Color.BLACK);mCirclePaint.setStyle(Style.STROKE);mCirclePaint.setStrokeWidth(1.f);mArcPaint.setColor(Color.GRAY);mArcPaint.setStyle(Style.FILL);mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);mLinePaint.setColor(Color.BLACK);mLinePaint.setStrokeWidth(1.f);mRectF = new RectF();Log.i("hq"," 构造函数中 mSweepAngle:"+mSweepAngle);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int size = getMeasuredWidth();setMeasuredDimension(size, size);mRectF.set(0, 0, getMeasuredWidth(), getMeasuredHeight());mArcPaint.setShader(new SweepGradient(size/2, size/2, Color.GRAY, Color.BLACK));}@Overrideprotected void onDraw(Canvas canvas) {int centerX = getMeasuredWidth() / 2;int centerY = getMeasuredHeight() / 2;canvas.save();canvas.rotate(mSweepAngle, centerX, centerY);canvas.drawArc(mRectF, 0, mSweepAngle, true, mArcPaint);canvas.restore();Log.i("hq", "mSweepAngle:" + mSweepAngle);canvas.drawLine(0, centerY, getMeasuredWidth(), centerY, mLinePaint);canvas.drawLine(centerX, 0, centerX, getMeasuredHeight(), mLinePaint);canvas.drawCircle(centerX, centerY, centerX / 2, mCirclePaint);canvas.drawCircle(centerX, centerY, centerX, mCirclePaint);}public void start() {mHandler.sendEmptyMessage(MSG_RUN);}private Handler mHandler = new Handler() {public void handleMessage(Message msg) {if(msg.what == MSG_RUN) {mSweepAngle+=2;if(mSweepAngle > 360) mSweepAngle = 0;postInvalidate();sendEmptyMessage(MSG_RUN);}}};}








0 0
原创粉丝点击