生活中我们要画一幅图片,需要工具,一个画笔🖌,一个画板(或是纸张),然后想要丰富多彩一点,我们还需要涂色。
Android画图--同样有三个基本对象:Color,Paint,Canvas
它们都位于android.graphics画图包下面。
- Color: 颜色对象,相当于现实生活中的 调料
- Paint : 画笔对象,相当于现实生活中画图用的 笔。对画笔的一些参数设置是很重要的。
- Canvas : 画布对象,相当于现实生活中画图用的画纸或者画布
三者结合,便能画出基本图形
一、Canvas
关于Canvas的获取方式有三种:
-
第一种:在View的OnDraw方法中,回调方法OnDraw会将Canvas做为参数传入,方法中直接使用即可。对于这方法,view在绘制之后onDraw 方法不会被反复调用,需要我们调用View的invalidate方法来触发相应view的onDraw方法再次被调用。这种方式是最常用的。
-
第二种:使用专门的SurfaceView的canvas来画图。这种方式最大的区别就是SurfaceView中定义了一个专门的线程来完成画图工作,应用程序不需要等待View的刷图,提高性能。这种方法主要用在游戏,高品质动画方面的画图。SurfaceView中使用SurfaceHolder.lockCanvas()来获取Canvas。
-
第三种:自己创建canvas来使用。
Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
需要注意的是,如果使用自定义的Canvas,我们最后依然需要通过调用系统提供的Canvas的Canvas.drawBitmap(Bitmap,...)方法,将canvas最终绘制出来。
------------------------------------------------------------
关于Canvas的使用
1.绘制点
void drawPoint(float x, float y, Paint paint)
画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。
void drawPoints (float[] pts, Paint paint)
绘制一组点,坐标位置由float数组指定
2.绘制直线
void drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
画线,参数一起始点的x轴位置,参数二起始点的y轴位置,参数三终点的x轴水平位置,参数四y轴垂直位置,最后一个参数为Paint对象。
void drawLines (float[] pts, Paint paint)
绘制一组线 ,坐标位置由float数组指定
3.绘制矩形
void drawRect (float left, float top, float right,float bottom, Paint paint)
绘制矩形,四个数值(矩形左上角和右下角两个点的坐标)来确定一个矩形
void drawRect(Rect r, Paint paint)
绘制矩形,参数一为Rect一个区域
void drawRect (RectF rect,Paint paint)
绘制矩形,参数一为RectF 一个区域
对于第二、三种方式,我们需要传入一个Rect或RectF
Rect rect = new Rect(100,100,800,400);
canvas.drawRect(rect,mPaint);
RectF rectF = new RectF(100.1f,100.1f,800.1f,400.1f);
canvas.drawRect(rectF,mPaint);
这两者的主要区别是:精度不一样。Rect是使用int类型作为数值,RectF是使用float类型作为数值
4.绘制圆形矩形
void drawRoundRect(@NonNull RectF rect, float r1, float r2, @NonNull Paint paint)
绘制圆角矩形,rx, ry分别是圆弧的圆心 和 半径,其中圆心用于确定位置,而半径用于确定大小
void drawRoundRect (float left,float top, float right, float bottom, float r1, float r2, Paint paint)
API level 21才添加的
5.绘制椭圆
void drawOval(@NonNull RectF oval, @NonNull Paint paint)
绘制椭圆
drawOval(float left, float top, float right, float bottom, Paint paint)
6.绘制圆
drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
绘制圆,cx,cy是圆心坐标,radius是半径,paint是画笔对象
7.绘制路径
void drawPath(Path path, Paint paint)
绘制一个路径,参数一为Path路径对象
8.绘制图片
void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
参数一就是我们常规的Bitmap对象,参数二是源区域(这里是bitmap),参数三是目标区域(应该在 canvas的位置和大小),参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。
9.绘制文本
void drawText(String text, float x, float y, Paint paint)
绘制文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。
void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
在路径上绘制文本,相对于上面第二个参数是Path路径对象
10.绘制弧形
void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,@NonNull Paint paint)
绘制弧形、扇形
11.画布的变化
void translate(float dx, float dy)
位移
void scale(float sx, float sy, float px, float py)
缩放
void rotate(float degrees)
旋转,默认旋转中心为原点
void rotate(float degrees, float px, float py)
第一个参数是旋转角度,后两个参数依旧是控制旋转中心点
二、Paint
void setARGB(int a, int r, int g, int b)
设置Paint对象颜色,参数一为alpha透明通道
void setAlpha(int a)
设置alpha不透明度,范围为0~255
void setAntiAlias(boolean aa)
是否抗锯齿
void setColor(int color)
设置颜色,这里Android内部定义的有Color类包含了一些常见颜色定义
void setStyle(Style style)
设置画笔样式为描边,画笔样式分三种:
1.Paint.Style.STROKE:描边
2.Paint.Style.FILL_AND_STROKE:描边并填充
3.Paint.Style.FILL:填充
void setFakeBoldText(boolean fakeBoldText)
设置伪粗体文本
void setLinearText(boolean linearText)
设置线性文本
void setTextAlign(Paint.Align align)
设置文本对齐
void setTextScaleX(float scaleX)
设置文本缩放倍数,1.0f为原始
void setTextSize(float textSize)
设置字体大小
void setUnderlineText(boolean underlineText)
设置下划线
setXfermode(Xfermode xfermode)
设置图像混合模式
关于这个方法可以看这个链接了解
http://www.cnblogs.com/tianzhijiexian/p/4297172.html
Rasterizer setRasterizer(Rasterizer rasterizer)
设置光栅化,实际效果并不明显
Typeface setTypeface(Typeface typeface)
设置字体,Typeface包含了字体的类型,粗细,还有倾斜、颜色等。
Typeface字体对象,这个类的作用是获取字体,创建字体,以及设置字体。
PathEffect setPathEffect(PathEffect effect)
设置路径效果
Shader setShader(Shader shader)
设置阴影
上面是画笔的基本方法,我们仔细看会发现几个独特的类和Paint配合使用,达到更好的效果
1.Shader:在使用paint设置画笔的同时,我们也可以给画笔来设置shader对象来为画笔增加更多的效果。Shader类专门用来渲染图像以及一些几何图形,Shader下面包括几个直接子类,分别是:
Shader类的使用,都需要先构建Shader对象,然后通过Paint的setShader方法设置渲染对象,然后设置渲染对象,然后再绘制时使用这个Paint对象即可。
BitmapShader : 图像渲染
LinearGradient : 线性渐变
RadialGradient : 环形渐变
SweepGradient : 扫描渐变---围绕一个中心点扫描渐变就像电影里那种雷达扫描
ComposeShader : 组合渲染
2.Typeface:一个字体的辅助类。一般情况下,我们就是使用字体文件创建一个Typeface,然后使用Typeface
//Default Font
Typeface mType = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
mPaint.setTypeface(mType);
// Custom Font : /assets/fonts/abc.ttf
Typeface mType = Typeface.createFromAsset(getContext().getAssets(),"fonts/aaa.ttf");
mPaint.setTypeface(mType);
//Custom Font : /sdcard/abc.ttf
Typeface mType = Typeface.createFromFile("sdcard/abc.ttf");
mPaint.setTypeface(mType);
3.PathEffect:会按照指定的路径绘制图形,完成一些特殊的效果。
使用PathEffect pe = new 一个具体的子类;
然后paint.setPathEffect( pe);即可
具体的子类如下:
CornerPathEffect:
这个类的作用就是将Path的各个连接线段之间的夹角用一种更平滑的方式连接,类似于圆弧与切线的效果。
一般的,通过CornerPathEffect(float radius)指定一个具体的圆弧半径来实例化一个CornerPathEffect。DashPathEffect:
这个类的作用就是将Path的线段虚线化。
构造函数为DashPathEffect(float[] intervals, float offset),其中intervals为虚线的ON和OFF数组,该数组的length必须大于等于2,phase为绘制时的偏移量。DiscretePathEffect:
这个类的作用是打散Path的线段,使得在原来路径的基础上发生打散效果。
一般的,通过构造DiscretePathEffect(float segmentLength,float deviation)来构造一个实例,其中,segmentLength指定最大的段长,deviation指定偏离量。PathDashPathEffect:
这个类的作用是使用Path图形来填充当前的路径,其构造函数为PathDashPathEffect (Path shape, float advance, float phase,PathDashPathEffect.Stylestyle)。
shape则是指填充图形,advance指每个图形间的间距,phase为绘制时的偏移量,style为该类自由的枚举值,有三种情况:Style.ROTATE、Style.MORPH和
Style.TRANSLATE。其中ROTATE的情况下,线段连接处的图形转换以旋转到与下一段移动方向相一致的角度进行转转,MORPH时图形会以发生拉伸或压缩等变形的情况与下一段相连接,TRANSLATE时,图形会以位置平移的方式与下一段相连接。ComposePathEffect:
组合效果,这个类需要两个PathEffect参数来构造一个实例,ComposePathEffect (PathEffect outerpe,PathEffect innerpe),表现时,会首先将innerpe表现出来,然后再在innerpe的基础上去增加outerpe的效果。
SumPathEffect:
叠加效果,这个类也需要两个PathEffect作为参数SumPathEffect(PathEffect first,PathEffect second),但与ComposePathEffect不同的是,在表现时,会分别对两个参数的效果各自独立进行表现,然后将两个效果简单的重叠在一起显示出来。
关于参数phase
在存在phase参数的两个类里,如果phase参数的值不停发生改变,那么所绘制的图形也会随着偏移量而不断的发生变动,这个时候,看起来这条线就像动起来了一样。
三、Color
1.系统颜色
可以通过 Color.颜色名,来获取颜色,应为是静态的,返回一个整数值
有以下几个: BLACK(黑色),BLUE(蓝色),CYAN(青色),GRAY(灰色),GREEN(绿色),RED(红色),WRITE(白色),YELLOW(黄色)等
Button btn = (Button) findViewById(R.id.btn);
btn.setBackgroundColor(Color.BLUE);
2.在XML中自定义颜色
<!--?xml version=1.0 encoding=utf-8?-->
<resources>
<color name="mycolor">#748751</color>
</resources>
//在java代码中的使用
int mycolor = getResources().getColor(R.color.mycolor);
Button btn = (Button) findViewById(R.id.btn);
btn.setBackgroundColor(mycolor);
3.在java代码中自定义颜色
//若已知颜色
int mycolor = 0xff123456;0x代表16进制FF代表透明度
//或调用静态的 argb方法,可以调出个性的颜色
int myColor=Color.argb(0xff, 255, 255, 255)
argb()方法的参数依次为透明度。后三个为红,绿,蓝的大小。范围都是[0-255],0至255 颜色依次加深