Android中绘制2D图形基础

时间:2022-05-26 11:12:03

Android中2D图形绘制基础


Android中的2D图形的绘制主要是靠Canvas(画布)和Paint(画笔)决定,其中Canvas可以用来绘制各种形状,而Paint可以用来描绘各种效果,比如颜色等等;

下面api简单使用了Paint最基本的用法;

setARGB(int a,int r,int g,int b): 设置绘制的颜色,a代表透明度,r,g,b代表颜色值。

setAlpha(int a): 设置绘制图形的透明度。

setColor(int color): 设置绘制的颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色。

setAntiAlias(boolean aa): 设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。

setDither(boolean dither): 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰

setFilterBitmap(boolean filter): 如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作, 加快显示速度,本设置项依赖于dither和xfermode的设置

setMaskFilter(MaskFilter maskfilter): 设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等

setColorFilter(ColorFilter colorfilter): 设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果

setPathEffect(PathEffect effect) 设置绘制路径的效果,如点画线等

setShader(Shader shader): 设置图像效果,使用Shader可以绘制出各种渐变效果

setShadowLayer(float radius ,float dx,float dy,int color):在图形下面设置阴影层,产生阴影效果, radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色

setStyle(Paint.Style style): 设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE

setStrokeCap(Paint.Cap cap): 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式, 如圆形样Cap.ROUND,或方形样式Cap.SQUARE

setSrokeJoin(Paint.Join join): 设置绘制时各图形的结合方式,如平滑效果等

setStrokeWidth(float width): 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度

setXfermode(Xfermode xfermode): 设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果

setFakeBoldText(boolean fakeBoldText): 模拟实现粗体文字,设置在小字体上效果会非常差

setSubpixelText(boolean subpixelText): 设置该项为true,将有助于文本在LCD屏幕上的显示效果

setTextAlign(Paint.Align align): 设置绘制文字的对齐方向

setTextScaleX(float scaleX): 设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果

setTextSize(float textSize): 设置绘制文字的字号大小

setTextSkewX(float skewX): 设置斜体文字,skewX为倾斜弧度

setTypeface(Typeface typeface): 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等

setUnderlineText(boolean underlineText): 设置带有下划线的文字效果

setStrikeThruText(boolean strikeThruText): 设置带有删除线的效果

setStrokeJoin(Paint.Join join): 设置结合处的样子,Miter:结合处为锐角, Round:结合处为圆弧:BEVEL:结合处为直线

setStrokeMiter(float miter):设置画笔倾斜度

setStrokeCap (Paint.Cap cap):设置转弯处的风格 其他常用方法:

float ascent( ):测量baseline之上至字符最高处的距离 

Android中绘制2D图形基础

float descent():baseline之下至字符最低处的距离

int breakText(char[] text, int index, int count, float maxWidth, float[] measuredWidth): 检测一行显示多少文字

clearShadowLayer( ):清除阴影层 


而画布(Canvas)提供了绘制各种图像形状的API,下面我们一一进行介绍;



绘制点只要知道当前点的坐标就可以了,同样绘制多个点只要知道多个点的坐标就可以了。

绘制View的这些坐标都是以父容器的左上角为坐标原点来计算的。

代码如下:

//绘制一点 蓝色
canvas.drawPoint(100, 100, mPaint); 
float[] pts = new float[]{        
      200, 300,
      200, 200,//代表一个点的xy坐标
      200, 400,
      200, 500,
//其中多个点的坐标存放于float数组中,成对表示一个点的坐标比如(200,200)
      200, 600
};
mPaint.setColor(Color.RED);
         250, 200,
canvas.drawPoints(pts, mPaint);//绘制多个点——红颜色 
float[] ptsOff = new float[]{
mPaint.setColor(Color.GREEN);
         250, 300,
         250, 400,
         250, 500,
         250, 600   
};
//这个方法和上面的是重载方法。第二个参数和第三个参数的含义看效果图就明白了
canvas.drawPoints(ptsOff,2, 4, mPaint);//绘制多个点——绿颜色


Android中绘制2D图形基础
看上图就很容易理解参数的含义;
float[] ptsOff = new float[]{
 250, 200,
 250, 300,
 250, 500,
         250, 400,
         250, 600
mPaint.setColor(Color.GREEN);
};
canvas.drawPoints(ptsOff,2, 4, mPaint);//绘制多个点——绿色
上面代码就相当于下面这样,第二个参数表示从原数组ptsOff下标为2的地方开始,4表示新形成新的数组的长度
float[] ptsOff1 = new float[]{
 250, 300,
 250, 400 
};
mPaint.setColor(Color.GREEN);
canvas.drawPoints(ptsOff1, mPaint);//绘制多个点——绿色

直线


绘制线只需要知道一条线的起始坐标和终止坐标就可以,绘制多条直线要知道多条直线的起始和终止坐标
//绘制一条直线 蓝色
canvas.drawLine(100, 100, 200, 100, mPaint);
float[] pts = new float[]{
        100, 300, 200, 300,
        100, 200, 200, 200,
mPaint.setColor(Color.RED);
        100, 400, 200, 400,
};
mPaint.setColor(Color.GREEN);
canvas.drawLines(pts, mPaint);//绘制多条直线——红色


float[] ptsOff = new float[]{
        250, 400, 350, 400,
        250, 200, 350, 200,
        250, 300, 350, 300,
};
canvas.drawLines(ptsOff, 4, 8, mPaint);//绘制多条直线——绿色


Android中绘制2D图形基础

矩形


绘制矩形只需要知道矩形左上角和右下角的坐标就可以了
//绘制矩形 蓝色
Rect rect = new Rect(100, 100, 300, 200);
canvas.drawRect(rect, mPaint);
canvas.drawRect(100, 250, 300, 350, mPaint);//绘制矩形——红色
mPaint.setColor(Color.RED);


mPaint.setColor(Color.GREEN);
canvas.drawRect(rectF, mPaint);//绘制矩形——绿色
RectF rectF = new RectF(100, 400, 300, 500);


Android中绘制2D图形基础
可能你已经注意到了Rect和RectF了,使用它们都可以绘制矩形,
只是它们的精度不同罢了,Rect是以int型来计量,RectF是以float来计量,还有就是一些API也不同。

 
 
 
 

圆角矩形


绘制圆角矩形有如下两条api可用,其中第二条需要api21才添加,所以尽量使用第一条就可以
drawRoundRect(RectF rect, float rx, float ry, Paint paint)
drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,Paint paint) 
先说上面第一个方法,第一个参数代表矩形,第二第三个参数代表矩形的x,y半径,最后是画笔
第二个方法,left top参数表示矩形的左上角xy坐标,right bottom代表矩形的左下角的坐标,这样构成一个矩形
rx ry代表矩形xy方向的半径,最后是画笔
绘制圆角矩形其实是以绘制矩形的内切圆角矩形,当rx和ry大于矩形长宽的一半时候,这是rx和ry按正好等于矩形长宽的一般来计算
下面先看看一般情况下的圆角矩形代码;
//绘制矩形
mPaint.setColor(Color.GRAY);
RectF rectFf = new RectF(100, 250, 300, 350);
canvas.drawRect(rectFf, mPaint);
//绘制圆角矩形 红色
mPaint.setColor(Color.RED);
canvas.drawRoundRect(rectFf, 30, 30, mPaint);


Android中绘制2D图形基础
上面代码运行效果
可以看到四个角都有一个圆弧,它是椭圆的圆弧.
上面绘制圆角矩形的一般情形下,下面再来看看特殊情况下圆角矩形的形状:
就是当rx和ry大于矩形长宽的一半时候,这时候rx和ry按正好等于矩形长宽的一般来计算并绘制形状
//绘制矩形
mPaint.setColor(Color.GRAY);
RectF rectF = new RectF(100, 100, 300, 200);
canvas.drawRect(rectF, mPaint);
//在绘制圆角矩形
//100是矩形rectF宽的一半,如果大于这个值,也按100算,同样高度也一样
mPaint.setColor(Color.BLUE
canvas.drawRoundRect();rectF, 100, 50, mPaint);

Android中绘制2D图形基础

圆形


drawCircle(float cx, float cy, float radius, Paint paint) 
cx,cy表示圆心的坐标,radius表示半径 
canvas.drawCircle(200, 200, 100, mPaint);//绘制圆形——蓝色
Android中绘制2D图形基础

椭圆


绘制椭圆使用的是如下两条api,第二个是在API21的时候加上的,以后尽量第一条
drawOval(RectF oval, Paint paint)
drawOval(float left, float top, float right, float bottom, Paint paint)
第一个方法oval表示椭圆的外接矩形
第二个方法前面四个参数构成一个矩形
代码:
RectF rectF = new RectF(100, 100, 300, 200);
mPaint.setColor(Color.GRAY);
//先绘制一个矩形
mPaint.setColor(Color.BLUE);
canvas.drawRect(rectF, mPaint);
//绘制椭圆
canvas.drawOval(rectF, mPaint);

Android中绘制2D图形基础

圆弧和扇形


绘制圆弧使用的是如下两条api,第二个是在API21的时候加上的,以后尽量第一条
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, 
Paint paint)
drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
第一个方法的纵oval表示圆弧的外接矩形,startAngle表示圆弧的开始角度,sweepAngle表示圆弧扫过的角度,
userCenter表示是否使用中心点,paint表示画笔
第二个方法前面四个参数构成一个矩形的左上角和右下角,其余的都一样 
看看代码和效果图:
//绘制一个灰色背景的矩形矩形
mPaint.setColor(Color.GRAY);
RectF rectF = new RectF(100, 100, 300, 200);
canvas.drawRect(rectF, mPaint);
//起始角度为0,偏转角度为90,并且使用中心点
mPaint.setColor(Color.BLUE);//绘制圆弧——蓝色
mPaint.setColor(Color.RED);//绘制圆弧——红色
canvas.drawArc(rectF, 0, 90, true, mPaint);
//起始角度为90,偏转角度为90,不使用中心点
canvas.drawArc(rectF, 90, 90, false, mPaint);

Android中绘制2D图形基础
上面两个同样都是偏转了90度的角度,蓝色区域使用了中心点,
画出来的形状是扇形,而红色没有使用中心点,画出来的是圆弧,
并且绘制的圆弧都是在矩形的内部。

Path(路径)

上面形状使用特定的方法可以很容易的进行绘制,但是大多数形状我们无法绘制,比如,三角形,多边形,心形等,这个时候就用到了Path,Path有许多方法,这里只介绍几个基本的;
Path的一些函数作用; 
     
     
moveTo()  移动下一次操作的起始位置
lineTo() 连接直线,在上一个点和当前点之间
setLastPoint() 设置当前路径下最后一个点的位置
close() 连接当前点和起始点,形成一个封闭的路径

使用colse()的时候,如果当前点没能形成一个闭合的路径,那么close()将不会有效果.
mPaint.setStyle(Paint.Style.STROKE);
Path path = new Path();
path.lineTo(300, 200);//lineTo
path.moveTo(200, 200);//moveTO
path.lineTo(250, 500);//

Android中绘制2D图形基础
 mPaint.setStyle(Paint.Style.STROKE);
Path path = new Path();
path.lineTo(300, 200);
path.moveTo(200, 200);
path.lineTo(250, 500);
path.moveTo(300, 300);//移动下次操作的起始点
path.close();//闭合路径
path.setLastPoint(250,600);//移动当前路径最后一点的位置
canvas.drawPath(path, mPaint);

由于这次形状无法闭合,所以close()会没有效果,setLastPont移动了最后一点的位置
Android中绘制2D图形基础

文本

drawText(String text, float x, float y, Paint paint)
* @param start The index of the first character in text to draw* @param end (end - 1) is the index of the last character in text to draw
drawText(String text, int start, int end, float x, float y,Paint paint)
* @param start The index of the first character in text to draw* @param end (end - 1) is the index of the last character in text to draw
drawText(CharSequence text, int start, int end, float x, float y,Paint paint)
drawText(char[] text, int index, int count, float x, float y,Paint paint)
上面四种绘制文本的方式差不多 
代码:
String text = "Android";
mPaint.setTextSize(50);
canvas.drawText(text, 100, 200, mPaint);//注意绘制文本使用的方法
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(1);
//绘制两条红色直线 也就是基线
canvas.drawLine(0, 200, 1000, 200, mPaint);
canvas.drawLine(100, 0, 100, 1000, mPaint);

运行代码效果图:
Android中绘制2D图形基础
上面两条红线分别代表绘制文本的基准线,竖直是100,水平是200,这样可以清楚的看到文本的绘制
String text = "Android";
mPaint.setTextSize(50);
canvas.drawText(text, 100, 200, mPaint);//注意绘制文本使用的方法
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(1);
//绘制两条红色直线 也就是基线
canvas.drawLine(0, 200, 1000, 200, mPaint);
canvas.drawLine(100, 0, 100, 1000, mPaint);


Android中绘制2D图形基础

上面drawText中的参数1和3,表示从字符串"Android"中下标索引为1开始截取,
3不是下标索引,表示结束位置,下标索引的范围[1,3)这个意思。所以此处是nd
Android中绘制2D图形基础
String text = "Android";
mPaint.setTextSize(50);
canvas.drawText(text.toCharArray(), 1, 3, 100, 200, mPaint);
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(1);
//绘制两条红色直线 也就是基线
canvas.drawLine(0, 200, 1000, 200, mPaint);
canvas.drawLine(100, 0, 100, 1000, mPaint);

跟上面不同的是此处1代表数组的下标,3代表数组的长度。所以此处是ndr
Android中绘制2D图形基础
drawPosText(String text,float[] pos, Paint paint)
drawPosText(char[] text, int index, int count,float[] pos,Paint paint)
上面连个方法很容易懂的,看代码
    String text = "Android";  
            10, 10,//A的坐标
    mPaint.setTextSize(10);
    float[] pos = new float[]{
            40, 40,//r的坐标
            20, 20,//n的坐标 
            30, 30,//d的坐标 
            50, 50,//o的坐标
    canvas.drawPosText(text, pos, mPaint);
            60, 60,//i的坐标
            70, 70//d的坐标
    };
    mPaint.setColor(Color.RED);
    canvas.drawLine(20, 0, 20, 1000, mPaint);
    mPaint.setStrokeWidth(1);
    //绘制多条基线 也就是基线
    canvas.drawLine(10, 0, 10, 1000, mPaint);
    canvas.drawLine(50, 0, 50, 1000, mPaint);
    canvas.drawLine(30, 0, 30, 1000, mPaint);
    canvas.drawLine(40, 0, 40, 1000, mPaint);
    canvas.drawLine(60, 0, 60, 1000, mPaint);
    canvas.drawLine(0, 30, 1000, 30, mPaint);
    canvas.drawLine(70, 0, 70, 1000, mPaint);
    canvas.drawLine(0, 10, 1000, 10, mPaint);
    canvas.drawLine(0, 20, 1000, 20, mPaint);
    canvas.drawLine(0, 40, 1000, 40, mPaint);
    canvas.drawLine(0, 70, 1000, 70, mPaint);
    canvas.drawLine(0, 50, 1000, 50, mPaint);
    canvas.drawLine(0, 60, 1000, 60, mPaint);

Android中绘制2D图形基础