1.自定义view有三点:
布局,绘制,触摸反馈。绘制是独立的,其辅助作用。接管和控制绘制,可以很方便的画出直方图,折现图,饼图等。
2.自定义绘制的实现:
重写view里面的onDraw()方法(view的主体方法,也是最常用的方法,TextView,ImageView都是onDraw()画的,参数是canvas参数,canvas.drawCircle(),它就会画一个圆出来,canvas画布之一,Android界面几乎是canvas画出来的,除了3d游戏需要opencv画以外),canvas.drawXxxx( xxx有circle,Path,paint加强版颜料,提供颜色和风格(是实心还是空心,粗细,阴影) ,,),
canvas里面有clipXxx裁切功能,超出的就剪掉,
还有放大缩小,拉扯四个顶点,图形变换,就是canvas几何变换(Matrix)
还有负责前景的,背景的与onDraw同级
paint设置颜色:
paint.setColor(Color.parseColor("#009688"));
canvas.drawRect(30, 30, 230, 180, paint);
paint.setColor(Color.parseColor("#FF9800"));
canvas.drawLine(300, 30, 450, 180, paint);
paint.setColor(Color.parseColor("#E91E63"));
canvas.drawText("HenCoder", 500, 130, paint);
drawRect(float left, float top, float right, float bottom, Paint paint) 画矩形
left
, top
, right
, bottom
是矩形四条边的坐标。
paint.setStyle(Style.FILL);
canvas.drawRect(100, 100, 500, 500, paint);
paint.setStyle(Style.STROKE);
canvas.drawRect(700, 100, 1100, 500, paint);
drawPoint(float x, float y, Paint paint) 画点
x
和 y
是点的坐标。点的大小可以通过 paint.setStrokeWidth(width)
来设置;点的形状可以通过 paint.setStrokeCap(cap)
来设置:ROUND
画出来是圆形的点,SQUARE
或 BUTT
画出来是方形的点。(点还有形状?是的,反正 Google 是这么说的,你要问问 Google 去,我也很懵逼。)
注:
Paint.setStrokeCap(cap)
可以设置点的形状,但这个方法并不是专门用来设置点的形状的,而是一个设置线条端点形状的方法。端点有圆头 (ROUND
)、平头 (BUTT
) 和方头 (SQUARE
) 三种,具体会在下一节里面讲。
paint.setStrokeWidth(20);
paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawPoint(50, 50, paint);
drawOval(float left, float top, float right, float bottom, Paint paint) 画椭圆
drawLine(float startX, float startY, float stopX, float stopY, Paint paint) 画线
startX
, startY
, stopX
, stopY
分别是线的起点和终点坐标。
canvas.drawLine(200, 200, 800, 500, paint);
drawPath(Path path, Paint paint) 画自定义图形
这个方法有点复杂,需要展开说一下。
前面的这些方法,都是绘制某个给定的图形,而 drawPath()
可以绘制自定义图形。当你要绘制的图形比较特殊,使用前面的那些方法做不到的时候,就可以使用 drawPath()
来绘制。
public class PathView extends View {
Paint paint = new Paint();
Path path = new Path(); // 初始化 Path 对象
......
{
// 使用 path 对图形进行描述(这段描述代码不必看懂)
path.addArc(200, 200, 400, 400, -225, 225);
path.arcTo(400, 200, 600, 400, -180, 225, false);
path.lineTo(400, 542);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path, paint); // 绘制出 path 描述的图形(心形),大功告成
}
}
Path
可以描述直线、二次曲线、三次曲线、圆、椭圆、弧形、矩形、圆角矩形。把这些图形结合起来,就可以描述出很多复杂的图形。下面我就说一下具体的怎么把这些图形描述出来。
Path
有两类方法,一类是直接描述路径的,另一类是辅助的设置或计算。
Path 方法第一类:直接描述路径。
这一类方法还可以细分为两组:添加子图形和画线(直线或曲线)
第一组: addXxx()
——添加子图形
addCircle(float x, float y, float radius, Direction dir) 添加圆
x
, y
, radius
这三个参数是圆的基本信息,最后一个参数 dir
是画圆的路径的方向。
路径方向有两种:顺时针 (
CW
clockwise) 和逆时针 (CCW
counter-clockwise) 。对于普通情况,这个参数填CW
还是填CCW
没有影响。它只是在需要填充图形 (Paint.Style
为FILL
或FILL_AND_STROKE
) ,并且图形出现自相交时,用于判断填充范围的。比如下面这个图形:
除此之外, Canvas
还可以绘制 Bitmap
和文字。
drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 画 Bitmap
绘制 Bitmap
对象,也就是把这个 Bitmap
中的像素内容贴过来。其中 left
和 top
是要把 bitmap
绘制到的位置坐标。它的使用非常简单。
drawBitmap(bitmap, 200, 100, paint);
位图(Bitmap),又称栅格图(英语:Raster graphics)或点阵图,是使用像素阵列(Pixel-array/Dot-matrix点阵)来表示的图像。
drawText(String text, float x, float y, Paint paint) 绘制文字
界面里所有的显示内容,都是绘制出来的,包括文字。 drawText()
这个方法就是用来绘制文字的。参数 text
是用来绘制的字符串,x
和 y
是绘制的起点坐标。
canvas.drawText(text, 200, 100, paint);
插播五: Paint.setTextSize(float textSize)
通过 Paint.setTextSize(textSize)
,可以设置文字的大小。
paint.setTextSize(18);
canvas.drawText(text, 100, 25, paint);
paint.setTextSize(36);
canvas.drawText(text, 100, 70, paint);
paint.setTextSize(60);
canvas.drawText(text, 100, 145, paint);
paint.setTextSize(84);
canvas.drawText(text, 100, 240, paint);
设置文字的位置和尺寸,这些只是绘制文字最基本的操作。文字的绘制具有极高的定制性,不过由于它的定制性实在太高了,所以我会在后面专门用一期来讲文字的绘制。这一期就不多讲了。
嗯……就这样吧。绘制部分第一节, Canvas
的 drawXXX()
系列方法和 Paint
的基本使用,就到这里
裁切和几何变换
Canvas.rotate(float degrees, float px, float py) 旋转
参数里的 degrees
是旋转角度
范围裁切有两个方法: clipRect()
和 clipPath()
。裁切方法之后的绘制代码,都会被限制在裁切范围内。
记得要加上 Canvas.save()
和 Canvas.restore()
来及时恢复绘制范围,所以完整代码是这样的:(先保存,再恢复)
canvas.save();
canvas.clipRect(left, top, right, bottom);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
canvas用的是view的坐标系,二维坐标系,x轴右正左负,y轴下正上负,camara是三位坐标系,x轴右正左负,y轴上正下负,z轴垂直view,内正外负,朝屏幕里是正的,(在z轴,往view做投影)
matrix能做一切几何变换
View.Translation.X(500)过度500,这不是动画
ViewPropertyAnimator
使用方式:View.animate()
后跟 translationX()
等方法,动画会自动执行。
view.animate().translationX(500);
不断调用,一点一点移动,这叫动画
在线程里不断更新它的位置,for循环更新它的过程,一点点更新view,慢慢的往右移(call属性动画) View.postLay
手写代码,设置监听器,太麻烦,可用属性动画的api,可能几行代码就给做出来了,只要告诉他,我要干什么,剩下的各种设定,各种计算工作,api都帮你完成了,这就是属性api动画的作用,它很方便,是一个动画工具而已。
ViewPropertyAnimator(最简单的属性动画)
使用方式:View.animate()
后跟 translationX()
等方法,动画会自动执行。
view.animate().translationX(500);
调用view.animate,在加上几行代码,描述出你要做出的动画就可以了,你调用了view.animate()方法,实际上它返回了一个ViewPropertyAnimator
动画:
是将两个动作做平滑的切换,而不是过度