Android绘图深度解析
转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)
Android绘图方法主要有两个步骤: (1)实现一个继承于View组件的类,并重写它的onDraw(Canavas canvas)方法; (2)显示定义的View子类,有两种方法:a.使用一个Activity来显示View子类,即 setContentView(new MyView(this, null));b.在Acitviy的布局文件中增加"包名.View子类"元素,Activiyty通过setContentView方法来使用该布局文件。下面我们来学习下Android绘制图形的三个最重要的API工具。 一、Android绘图三大API 1.Canvas类
(1)功能:Canvas代表了"依附"于指定View的画布,通过Canvas类的成员方法能够实现绘制各种图形。绘制一个图形由四部分组成:Bitmap、Canvas、Path/Rect/text等、Paint,其中Bitmap为绘制图形存放的像素位图,Canvas用于提供绘制图像方法、Paint为画笔、Path/Rect/text等分别为绘制图形的(轨迹/矩形/文本) (2)构造方法 Canvas() :构造空的canvas对象 Canvas(Bitmap bitmap) :构造一个Canvas对象,并指定其bitmap (3)常用方法
boolean clipRegion(Regionregion):剪切指定区域
void drawBitmap(Bitmapbitmap, float left, float top,Paintpaint):在指定点(x,y)使用指定的画笔paint绘制位图
void drawBitmap(Bitmapbitmap,Rectsrc,Rectdst,Paintpaint):在指定点(x,y)绘制从源位图中"挖取"的一块
void drawCircle(float cx, float cy, float radius,Paintpaint):绘制原点为(cx,cy),半径为radius的圆
void drawLine(float startX, float startY, float stopX, float stopY,Paintpaint):绘制一条起点为(startX,startY),终点为(stopX,stopY)直线
void drawLines(float[] pts, int offset, int count,Paintpaint):绘制多条直线,其中pts为一个浮点型数组提供绘制一条直接所需的数据(4个/条),count为绘制直线的条数
void drawOval(RectFoval,Paintpaint):绘制一个椭圆,oval为绘制椭圆的矩形边界
void drawPath(Pathpath,Paintpaint):沿着路径path绘制图形
void drawPoint(float x, float y,Paintpaint):绘制一个点(x,y)
void drawPoints(float[] pts, int offset, int count,Paintpaint):绘制pts数组中的多个点(2个值/点)
void drawRect(float left, float top, float right, float bottom,Paintpaint):绘制一个矩形,其参数为距离屏幕边界的距离(边界为0)
void drawRoundRect(RectFrect, float rx, float ry,Paintpaint):使用指定的画笔绘制圆角矩形,其中rect为矩形边界、rx/ry分别为以矩形顶点为(0,0)相对位置圆的x半径、y半径
void drawText(Stringtext, float x, float y,Paintpaint):以(x,y)为原点,使用指定画笔绘制文本
void drawTextOnPath(Stringtext,Pathpath, float x, float y,Paintpaint):以(x,y)为原点,使用指定的画笔沿着指定路径绘制文本
int getHeight():返回当前图层的高度
int getWidth():返回当前绘图层的宽度
void rotate(float degrees):对Canvas执行旋转变换;
void setBitmap(Bitmapbitmap):指定Canvas(画布)的位图Bitmap
void translate(float dx, float dy):相对于当前位置移动Canvas。向右移动dx距离(dx为负数即向左移动);向下移动dy距离(dy为负数即向上移动)
void skew(float sx,float sy):对Canvas执行倾斜变换

2.Paint类


(1)功能:Paint代表了Canvas上的画笔,Paint类主要用于设置绘制风格,包括画笔的颜色、画笔笔触粗细、填充风格等。 (2)构造方法 Paint() :使用默认设置构造一个Paint对象 Paint(int flags) :使用指定flags构造一个Paint对象 Paint(Paint paint) :使用已有画笔的设置构造一个新的Paint对象 (3)常用方法
void reset():恢复画笔到默认配置
void setARGB(int a, int r, int g, int b):设置画笔透明度和颜色,其参数分别代表透明度、红色、绿色、蓝色
void setAlpha(int a):设置画笔的透明度
void setAntiAlias(boolean aa):设置是否抗锯齿
void setColor(int color):设置画笔的颜色
void setFlags(int flags):设置画笔的flags(HINTING_OFF、HINTING_ON等)
void setHinting(int mode):设置画笔的提示模式
PathEffect setPathEffect(PathEffecteffect):设置绘制路径时的路径效果(ComposePathEffect, CornerPathEffect, DashPathEffect, DiscretePathEffect, PathDashPathEffect, SumPathEffect)
Rasterizer setRasterizer(Rasterizerrasterizer)
Shader setShader(Shadershader):设置画笔的填充效果(BitmapShader, ComposeShader, LinearGradient, RadialGradient, SweepGradient)
void setShadowLayer(float radius, float dx, float dy, int color):设置阴影效果
void setStrokeJoin(Paint.Joinjoin):设置画笔转弯处的连接风格(BEVEL-直线、MITER -锐角、ROUND-圆弧)
void setStrokeWidth(float width):设置画笔宽度
void setStyle(Paint.Stylestyle):设置Paint的填充风格(FILL-、FILL_AND_STROKE、STROKE)
void setTextAlign(Paint.Alignalign):设置绘制文本时的文字对齐方式(CENTER -居中、LEFT-靠左、RIGHT -靠右:以(x,y)为中心)
void setTextSize(float textSize):设置绘制文本的文字大小
3.Path类
(1)功能:Android提供的Path类预先在View上将N个点连成一条"路径",然后调用Canvas的drawPath(path,paint)方法即可沿着路径绘制图形。另外,Android还提供了PathEffect来定义绘制路径图形效果,其包含ComposePathEffect、CornerPathEffect、DashPathEffect、DiscretePathEffect、PathDashPathEffect、SumPathEffect六种效果 (2)构造方法 Path():构造一个Path对象 Path(Path src) :从另一个Path对象构造一个新的Path对象 (3)常用方法
boolean isEmpty():判定Path对象是否为空(即不包含直线或曲线),如果为空返回true
void lineTo(float x, float y):增加一条从上一点到当前点(x,y)的直线
void moveTo(float x, float y):设置下一个轮廓的开始点(x,y)
void rLineTo(float dx, float dy):以坐标为参照增加一条从上一点到当前点(x,y)的直线
void rMoveTo(float dx, float dy):以坐标为参照设置下一个轮廓的开始点(x,y)
void reset():删除Path对象的所有直线和曲线
void set(Pathsrc):将当前Path对象的内容替换为对象src所包含的内容
void setFillType(Path.FillTypeft):设置路径的填充类型
void setLastPoint(float dx, float dy):设置路径的最后一个点的坐标为(x,y)
void transform(Matrixmatrix):通过matrix转换该路径中的点
void
close() :释放资源

二、常见几何图形/文本的绘制方法 1.画笔常用设置 (1)无填充风格 new Paint().setAntiAlias(true); // 去锯齿 .setColor(Color.BLUE); // 设置画笔为蓝色 .setStyle(Paint.Style.STROKE); // 设置画笔的填充风格 (2)有填充风格 new Paint().setStyle(Paint.Style.FILL); //填充整个图形区域 .setColor(Color.RED); //填充颜色为红色 (3)设置渐变器 Shader mShader = new LinearGradient(0,0,40,60 ,new int[] {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW} ,null,Shader.TileMode.REPEAT); new Paint().setShader(mShader); .setShadowLayer(45, 10, 10, Color.GRAY); 2.常见几何图形/文本(屏幕左上角为参考原点(0,0,屏幕边界均为0)) (1)绘制圆形 :原点为(30,30),半径为30. Canvas canvas = new Canvas(); canvas.drawCircle(30, 30, 30, paint); (2)绘制正方形:以屏幕左上角为参考原点(0,0),(左,上)=(30,30)、(右,下)=(200,200) Canvas canvas = new Canvas();
canvas.drawRect(30, 30, 200, 200, paint); Android笔记二十.Android绘图深度解析_第1张图片
(3)绘制矩形 Canvas canvas = new Canvas(); canvas.drawRect(10, 150, 70, 190, paint); (4)绘制圆角矩形:re1为相对于屏幕为(0,0)点,坐标为(30,30)和(200,200)的矩形;(30,30)为相对矩形的四个顶点为零点绘制在矩形内部的圆点为半径x、y轴为15的=半径的圆,最后矩形四个角取与圆的公共部分。圆的半径越大,矩形四个角越圆。 Canvas canvas = new Canvas();
RectF re1 = new RectF(30, 30, 200, 200); canvas.drawRoundRect(re1, 15, 15, paint); Android笔记二十.Android绘图深度解析_第2张图片
(5)绘制椭圆:以屏幕左上角为参照零点(0,0),2a=100-30,2b=310-260 Canvas canvas = new Canvas();
RectF re11 = new RectF(30,260,100, 310); canvas.drawOval(re11, paint); Android笔记二十.Android绘图深度解析_第3张图片
(6)绘制三角形(借助Path类):以屏幕左上角为参照零点(0,0),起点为(10,340)、 Canvas canvas = new Canvas();
Path path1 = new Path(); path1.moveTo(10, 340); path1.lineTo(70, 340); path1.lineTo(40, 290); path1.close(); canvas.drawPath(path1, paint); Android笔记二十.Android绘图深度解析_第4张图片
(7)绘制五角形(借助Path类) Canvas canvas = new Canvas();
Path path2 = new Path(); path2.moveTo(26, 360); path2.lineTo(54, 360); path2.lineTo(70, 392); path2.lineTo(40, 420); path2.lineTo(10, 392); path2.close(); canvas.drawPath(path2, paint); (8)绘制文本:字符串起始位置为(30,30) new Paint().setTextSize(30); //文本字体大小 .setShader(null); //无阴影效果 Canvas canvas = new Canvas();
canvas.drawText(getResources().getString(R.string.circle), 30, 30, paint); Android笔记二十.Android绘图深度解析_第5张图片
3.源码实战:绘制图形 (1)继承View的子类MyView.java
<span style="font-family:Times New Roman;"><span style="font-size:18px;">package com.example.canvaspaint;public class MyView extends View { // 1.构造方法 public MyView(Context context, AttributeSet set) {  super(context, set); } // 2.重写onDraw方法进行绘图 @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  // a.初始化画布、画笔  canvas.drawColor(Color.WHITE); // 设置画布绘制成白色  Paint paint = new Paint();  paint.setAntiAlias(true); // 去锯齿  paint.setColor(Color.BLUE); // 设置画笔为蓝色  paint.setStyle(Paint.Style.STROKE); // 设置画笔的填充风格  /*------------------------无填充风格绘制----------------------------*/  // b.绘制圆形  canvas.drawCircle(30, 30, 30, paint);  // c.绘制正方形  canvas.drawRect(10, 30, 50, 50, paint);  // d.绘制矩形  canvas.drawRect(30, 30, 200, 200, paint);  // e.绘制圆角矩形  RectF re1 = new RectF(30,30, 200, 200);  canvas.drawRoundRect(re1, 30,30, paint);  // f.绘制椭圆  RectF re11 = new RectF(30,30,100, 80);  canvas.drawOval(re11, paint);   //g.定义一个Path对象,封闭成一个三角形并根据Path对象绘制  Path path1 = new Path();  path1.moveTo(10, 340);  path1.lineTo(70, 340);  path1.lineTo(40, 290);  path1.close();  canvas.drawPath(path1, paint);  // h.根据Path绘制五角形  Path path2 = new Path();  path2.moveTo(26, 360);  path2.lineTo(54, 360);  path2.lineTo(70, 392);  path2.lineTo(40, 420);  path2.lineTo(10, 392);  path2.close();  canvas.drawPath(path2, paint);  /*------------------------设置填充风格后绘制----------------------------*/  paint.setStyle(Paint.Style.FILL);  paint.setColor(Color.RED);  // b.绘制圆形  canvas.drawCircle(120, 40, 30, paint);  // c.绘制正方形  canvas.drawRect(90, 80, 150, 140, paint);  // d.绘制矩形  canvas.drawRect(90, 150, 150, 190, paint);  // e.绘制圆角矩形  RectF re2 = new RectF(90, 200, 70, 230);  canvas.drawRoundRect(re2, 15, 15, paint);  // f.绘制椭圆  RectF re22 = new RectF(90, 240, 150, 270);  canvas.drawOval(re22, paint);  // g.定义一个Path对象,封闭成一个三角形并根据Path对象绘制  Path path3 = new Path();  path3.moveTo(90, 340);  path3.lineTo(150, 340);  path3.lineTo(120, 290);  path3.close();  canvas.drawPath(path3, paint);  // h.根据Path绘制五角形  Path path4 = new Path();  path4.moveTo(106, 360);  path4.lineTo(134, 360);  path4.lineTo(150, 392);  path4.lineTo(120, 420);  path4.lineTo(90, 392);  path4.close();  canvas.drawPath(path4, paint); /*------------------------设置渐变器后绘制----------------------------*/   Shader mShader = new LinearGradient(0,0,40,60,new int[] {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},null,Shader.TileMode.REPEAT);  paint.setShader(mShader);  paint.setShadowLayer(45, 10, 10, Color.GRAY);  //b.绘制圆形  canvas.drawCircle(200,40,30, paint);  //c.绘制正方形  canvas.drawRect(170,80,230,140,paint);  //d.绘制矩形  canvas.drawRect(170, 150, 230, 190, paint);  //e.绘制圆角矩形  RectF re3= new RectF(170,200,230,230);  canvas.drawRoundRect(re3, 15, 15, paint);  //f.绘制椭圆  RectF re33 = new RectF(170,240,230,270);  canvas.drawOval(re33, paint);  //g.定义一个Path对象,封闭成一个三角形并根据Path对象绘制  Path path5 = new Path();  path5.moveTo(170, 340);  path5.lineTo(230, 340);  path5.lineTo(200, 290);  path5.close();  canvas.drawPath(path5, paint);  //h.根据Path绘制五角形  Path path6 = new Path();  path6.moveTo(186, 360);  path6.lineTo(241, 360);  path6.lineTo(230, 392);  path6.lineTo(200, 420);  path6.lineTo(170, 392);  path6.close();  canvas.drawPath(path6, paint);   /*---------------设置字符大小后绘制---------------*/  paint.setTextSize(30);  paint.setShader(null);// //绘制7个字符串  canvas.drawText(getResources().getString(R.string.circle), 30, 30, paint);  canvas.drawText(getResources().getString(R.string.square), 240, 120, paint);  canvas.drawText(getResources().getString(R.string.rect), 240, 175, paint);  canvas.drawText(getResources().getString(R.string.round_rect), 230, 220, paint);  canvas.drawText(getResources().getString(R.string.oval), 240, 260, paint);  canvas.drawText(getResources().getString(R.string.triangle), 240, 325, paint);  canvas.drawText(getResources().getString(R.string.pentagon), 240, 390, paint); }}</span></span>

(2)应用界面显示该View子类CanvasTest.java
<span style="font-family:Times New Roman;"><span style="font-size:18px;">package com.example.canvaspaint;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;public class CanvasTest extends ActionBarActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new MyView(this, null));    }}</span></span>
效果演示:

二、Path类的使用
1.Path使用 Canvas沿着路径绘制图形,我们可以这样来定义一条路径:(1)构造一个Path对象;(2)调用Path的moveTo(x,y)方法设定路径的起点;(3)调用lineTo(x,y)方法设定下一个点的位置。 (1)设置Path路径效果:首先需要创建一个PathEffect子类对象,然后再调用Piant的setPathEffect(PathEffect p)方法即可。 (2)沿着路径绘制文本:首先需要设定路径的形状,然后设置好画笔并调用Canvas的drawPath(Path path,Paint paint)方法沿着路径绘制图形,最后调用Canvas的drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)方法绘制路径文本,其中hOffset为相对于路径起点距离的水平位置,hOffset为相对于路径上或下距离。 2.源码实战: (1)PathTest.java:使用PathEffect类的6个子类实现6种不同的路径绘制效果
<span style="font-family:Times New Roman;"><span style="font-size:18px;">package com.example.android_path;public class PathTest extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new MyView(this));    }    /*-----------------------构造方法---------------------------*/    class MyView extends View    {  float phase;     PathEffect[] effects = new PathEffect[7];     int[] colors;     private Paint paint;     Path path;     public MyView(Context context) {   super(context);   //1.初始化画笔Paint   paint = new Paint();//实例化一个(画笔)Paint对象   paint.setStyle(Paint.Style.STROKE);//设置Paint的填充风格   paint.setStrokeWidth(4);   //2.创建并初始化Path   path = new Path();   path.moveTo(0, 0);   for(int i=1;i<=15;i++)   {    //生成15个点,随机生成它们的Y坐标,并将它们生成一条Path    path.lineTo(i*20, (float)Math.random()*60);   }   //3.初始化7个颜色   colors = new int[] {Color.BLACK,Color.RED,Color.BLUE,Color.GRAY,Color.GREEN,Color.MAGENTA,Color.YELLOW};  }       /*-----------------------绘图---------------------------*/      @Override  protected void onDraw(Canvas canvas) {   super.onDraw(canvas);   canvas.drawColor(Color.WHITE);//将画布背景填充成白色   //4.初始化7种路径效果   effects[0]=null; //a.不使用路径效果   effects[1] = new CornerPathEffect(10); //b.初始化CornerPathEffect   effects[2] = new DiscretePathEffect(3.0f,5.0f); //c.初始化DiscretePathEffect   effects[3] = new DashPathEffect(new float[] {20,10,5,10}, phase); //d.初始化DashPathEffect   Path p = new Path();   p.addRect(0, 0, 8, 8, Path.Direction.CCW);   effects[4] = new PathDashPathEffect(p, 12, phase, PathDashPathEffect.Style.ROTATE);//e.初始化PathDashPathEffect   effects[5] = new ComposePathEffect(effects[2],effects[3]); //f.初始化ComposePathEffect   effects[6] = new SumPathEffect(effects[4], effects[3]); //g.初始化SumPathEffect   //5.将画布移动到(8,8)处开始绘制,依次使用7中不同路径效果、7中不同的颜色来绘制路径   canvas.translate(8, 8);   for(int i=0;i<effects.length;i++)   {    paint.setPathEffect(effects[i]);    paint.setColor(colors[i]);    canvas.drawPath(path, paint);    canvas.translate(0, 60);   }   //6.改变phase值,形成动画效果   phase +=1;   invalidate();  }    }}</span></span>

效果演示: Android笔记二十.Android绘图深度解析_第6张图片
分析:在上面的程序中,当定义DashPathEffect、PathDashPathEffect时可以指定一个phase参数,该参数用于指定路径效果的相位,当该phase参数不断地变化时,程序将不停得绘制该View组件,就会产生动画效果。另外,View的invalidate()方法就是使当前的View视图失效然后再次调用View的onDraw(Canvas canvas)方法重新绘图,需要注意的是invalidate()方法只能在UI线程中使用。 (2)PathText.java:沿着路径绘制文本
<span style="font-family:Times New Roman;"><span style="font-size:18px;">package com.example.path;/*沿着Path绘制文本*/public class PathText extends Activity { @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(new ViewText(this)); } class ViewText extends View {  final String DRAW_STR = "何以笙箫默";  Path[] paths = new Path[3];  Paint paint;    /*----------------------构造方法--------------------------*/    public ViewText(Context context) {   super(context);   paths[0] = new Path();   paths[0] .moveTo(0, 0);     //第一条路径:自动生成7个点连成一条线    for(int i=1;i<=7;i++)           {     paths[0].lineTo(i*30, (float)Math.random()*30);   }    //第二条路径:为一个椭圆(200,120)   paths[1] = new Path();   RectF rectF = new RectF(0,0,200,120);   paths[1].addOval(rectF, Path.Direction.CCW);  //第三条路径:为一条圆弧   paths[2] = new Path();   paths[2].addArc(rectF, 60, 180);   //2.初始化画笔   paint = new Paint();   paint.setAntiAlias(true);   paint.setColor(Color.RED);   paint.setStrokeWidth(1);  }  /*-------------------------绘图---------------------------------*/  @Override  protected void onDraw(Canvas canvas) {   super.onDraw(canvas);   canvas.drawColor(Color.WHITE); //设置画布背景为白色   canvas.translate(40, 40);   //a.设置从右边开始绘制(右对齐)   paint.setTextAlign(Paint.Align.RIGHT);   paint.setTextSize(20);   //b.绘制第一条路径   paint.setStyle(Paint.Style.STROKE); //绘制路径   canvas.drawPath(paths[0],paint);   paint.setStyle(Paint.Style.FILL);//沿着路径绘制一段文本   canvas.drawTextOnPath(DRAW_STR, paths[0], -8, 20, paint);    //对Canvas进行坐标变换,画布下移120    canvas.translate(0, 60);   //c.绘制第二条路径   paint.setStyle(Paint.Style.STROKE);//绘制路径   canvas.drawPath(paths[1], paint);   paint.setStyle(Paint.Style.FILL); //沿着路径绘制一段文本   canvas.drawTextOnPath(DRAW_STR, paths[1], -20, 20, paint);    //对Canvas进行坐标变换,画布下移120    canvas.translate(0, 120);   //d.绘制第三条路径   paint.setStyle(Paint.Style.STROKE);//绘制路径   canvas.drawPath(paths[2], paint);   paint.setStyle(Paint.Style.FILL); //沿着路径绘制一段文本   canvas.drawTextOnPath(DRAW_STR, paths[2], -10, 20, paint);     }   }}</span></span>
效果演示: Android笔记二十.Android绘图深度解析_第7张图片

更多相关文章

  1. Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩
  2. Android 监听U盘插入和拔出并获取U盘文件路径
  3. Android Studio编译动态替换清单文件AndroidManifest.xml内容(找
  4. android把字符串内容保存到指定路径
  5. android 获取SD卡的图片及其路径
  6. android 强制修改adb pull 文件的路径

随机推荐

  1. Android apk 签名总结
  2. android的EditText里文字和图片混合编辑
  3. Android(安卓)studio无法连接识别检测各
  4. 《Android第一行代码》笔记
  5. Android建立dialog
  6. Android录制屏幕的实现方法
  7. Android学习App调试的几个命令实践
  8. Android数据保存之SharedPreference
  9. [置顶] Activity启动模式 及 Intent Flag
  10. React Native如何适配iOS \ Android样式