一、如何创建自定义的View类
①、创建一个继承android.view.View类的Java类,并且重写构造方法(至少需要重写一个构造方法)
②、根据需要重写其他方法
③、在项目的活动中,创建并实例化自定义的View类,然后将其添加到布局管理器中(添加到布局管理器的方法:布局管理器.addView())
二、View类常用的函数
①、onDraw() 当组件将要绘制它的内容时
②、onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法
③、onMeasure() 检测View组件及其子组件的大小
④、onLayout() 当该组件需要分配其子组件的位置、大小时
⑤、onSizeChange() 当该组件的大小被改变时
⑥、onKeyDown 当按下某个键盘时
⑦、onKeyUp 当松开某个键盘时
⑧、onTrackballEvent 当发生轨迹球事件时
⑨、onTouchEvent 当发生触屏事件时
⑩、onWindowFocusChanged(boolean) 当该组件得到、失去焦点时
11)、onAtrrachedToWindow() 当把该组件放入到某个窗口时
12)、onDetachedFromWindow() 当把该组件从某个窗口上分离时触发的方法
13)、onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发的方法
三、将自定义的Viewl类添加到相对应的窗口
方式一:
布局管理器 变量名 = (布局管理器)findViewById(R.id.ID)
类 变量名A = new 类(this)
布局管理器.addView(变量名A)
方式二:
在xml布局中添加
四、Android自定义View的构造函数
有两种方式自定义构造函数
方式一:
每个构造函数分别调用基类的构造函数,再调用一个公共的初始化方法做额外的初始化工作
- 1 public class MyView extends ListView {
- 2 public MyView(Context context) {
- 3 super(context);
- 4 sharedConstructor();
- 5 }
- 6
- 7 public MyView(Context context, AttributeSet attrs) {
- 8 super(context, attrs);
- 9 sharedConstructor();
- 10 }
- 11
- 12 public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
- 13 super(context, attrs, defStyleAttr);
- 14 sharedConstructor();
- 15 }
- 16
- 17 private void sharedConstructor() {
- 18 // Do some initialize work.
- 19 }
- 20 }
方式二:
级联式调用,每一个构造函数调用比它多一个参数的构造函数,最后一个构造函数调用基类的构造函数,最后在做一些额外的初始化工作
- 1 public class MyView extends ListView {
- 2 public MyView(Context context) {
- 3 this(context, null);
- 4 }
- 5
- 6 public MyView(Context context, AttributeSet attrs) {
- 7 this(context, attrs, 0);
- 8 }
- 9
- 10 public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
- 11 super(context, attrs, defStyleAttr);
- 12
- 13 // Other initialize work.
- 14 }
- 15 }
注:
建议采用第一种方式。因为第二种方法在某些情况下会出现问题,比如你自定义的View继承自ListView或TextView时,ListView或TextView内部的构造函数有一个默认的defStyle, 第二种方法调用时defStyle会传入0,这将覆盖基类中默认的defStyle,进而导致一系列问题。
五、Canvas 和 Paint
Canvas表示画布,Paint代表画笔
1)、Paint的属性
- // 设置字体颜色
- paint.setColor(Color.RED);
- // 防锯齿
- paint.setAntiAlias(true);
-
- //设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果
- paint.setColorFilter(ColorFilter);
-
- //如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加 //快显示
- //速度,本设置项依赖于dither和xfermode的设置
- paint.setFilterBitmap(true);
-
- //当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度
- paint.setStrokeWidth(10f);
- //设置绘制路径的效果,如点画线等
- paint.setPathEffect(PathEffect);
-
- //设置图像效果,使用Shader可以绘制出各种渐变效果
- paint.setShader(Shader);
-
- //设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等
- paint.setMaskFilter(MaskFilter);
-
- //在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
- paint.setShadowLayer(float radius ,float dx,float dy,int color);
-
- //设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE
- paint.setStyle(Paint.Style);
-
- //当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,圆形样式ROUND,或方形样式SQUARE BUTT
- paint.setStrokeCap(Paint.Cap);
-
- //设置绘制时画笔与图形的结合方式,METER\ROUND\BEVEL 平滑效果
- paint.setSrokeJoin(Paint.Join);
-
- // 字体下划线
- paint.setUnderlineText(true);
- // 暂时不知,有清楚的可以告诉我,谢谢
- paint.setLinearText(true);
- // 字体加粗
- paint.setFakeBoldText(true);
- // 防抖动
- paint.setDither(true);
- // 透明度
- paint.setAlpha(a);
2)、如何获取一个Canvas对象
方式一:通过重写View.onDraw方法,View中的Canvas对象会被当做参数传递过来,我们操作这个Canvas,效果会直接反应在View中
方式二:自己创建一个Canvas对象。从上面的基本要素可以明白,一个Canvas对象一定是结合了一个Bitmap对象的。所以一定要为一个Canvas对象设置一个Bitmap对象
- 1 //得到一个Bitmap对象,当然也可以使用别的方式得到。但是要注意,改bitmap一定要是mutable(异变的)
- 2 Bitmap b = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);
- 3 Canvas c = new Canvas(b);
- 4 /*先new一个Canvas对象,在调用setBitmap方法,一样的效果
- 5 * Canvas c = new Canvas();
- 6 * c.setBitmap(b);
- 7 */
方式三:调用SurfaceHolder.lockCanvas(),返回一个Canvas对象;可以在 surfaceView 或 TextureView中使用
2.1)、Canvas可以绘制的内容
- //填充
- drawARGB(int a, int r, int g, int b)
- drawColor(int color)
- drawRGB(int r, int g, int b)
- drawColor(int color, PorterDuff.Mode mode)
- //几何图形
- canvas.drawArc //(扇形)
- canvas.drawCircle //(圆)
- canvas.drawOval //(椭圆)
- canvas.drawLine //(线)
- canvas.drawPoint //(点)
- canvas.drawRect //(矩形)
- canvas.drawRoundRect //(圆角矩形)
- canvas.drawVertices //(顶点)
- cnavas.drawPath //(路径)
- //图片
- canvas.drawBitmap //(位图)
- canvas.drawPicture //(图片)
- //文本
- canvas.drawText
//Canvas绘制常用图形的方法如下:
绘制直线:canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint);
绘制矩形:canvas.drawRect(float left, float top, float right, float bottom, Paint paint);
绘制圆形:canvas.drawCircle(float cx, float cy, float radius, Paint paint);
绘制字符:canvas.drawText(String text, float x, float y, Paint paint);
绘制图形:canvas.drawBirmap(Bitmap bitmap, float left, float top, Paint paint);
2.1)、Canvas的保存和回滚
Canvas还提供了保存和回滚属性的方法(save和restore),比如你可以先保存目前画纸的位置(save),然后旋转90度,向下移动100像素后画一些图形,画完后调用restore方法返回到刚才保存的位置
- 1 /**
- 2 * 保存当前的matrix和clip到私有的栈中(Skia内部实现)。任何matrix变换和clip操作都会在调用restore的时候还原。
- 3 * @return 返回值可以传入到restoreToCount()方法,以返回到某个save状态之前。
- 4 */
- 5 public native int save();
- 6
- 7
- 8
- 9 /**
- 10 * 传入一个标志,来表示当restore 的时候,哪些参数需要还原。该参数定义在Canvas中,参照下面。
- 11 * save()方法默认的是还原matrix和clip,但是可以使用这个方法指定哪些需要还原。并且只有指定matrix和clip才有效,其余的几个参数是
- 12 * 用于saveLayer()和saveLayerAlpha()方法 的。
- 13 */
- 14 public native int save(int saveFlags);
- 15
- 16
- 17 /**
- 18 * 回到上一个save调用之前的状态,如果restore调用的次数大于save方法,会出错。
- 19 */
- 20 public native void restore();
- 21
- 22 /**
- 23 * 返回栈中保存的状态,值等译 save()调用次数-restore()调用次数
- 24 */
- 25 public native int getSaveCount();
- 26
- 27
- 28
- 29
- 30 /**
- 31 * 回到任何一个save()方法调用之前的状态
- 32 */
- 33 public native void restoreToCount(int saveCount);
- 34
- 35
- 36
- 37 /**saveFlags的参数*/
- 38 public static final int MATRIX_SAVE_FLAG = 0x01;//需要还原Matrix
- 39 public static final int CLIP_SAVE_FLAG = 0x02;//需要还原Clip
- 40 /**下面三个参数在saveLayer的时候使用,具体作用,没有搞明白*/
- 41 public static final int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
- 42 public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
- 43 public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
- 44 public static final int ALL_SAVE_FLAG = 0x1F; //还原所有
- 45
- 46 /*关于saveLayer的具体flags还不大明白它的含义,具体怎么使用在下面例子中*/
- 47 public int saveLayer(RectF bounds, Paint paint, int saveFlags)
- 48 public int saveLayer(float left, float top, float right, float bottom,
- 49 Paint paint, int saveFlags)
- 50 public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
- 51 public int saveLayerAlpha(float left, float top, float right, float bottom,
- 52 int alpha, int saveFlags)
2.3)、Canvas的转换
Canvas还提供了一系列位置转换的方法:rorate、scale、translate、skew(扭曲)等
- 1 @Override
- 2 protected void onDraw(Canvas canvas) {
- 3 canvas.translate(100, 100);
- 4 canvas.drawColor(Color.RED);//可以看到,整个屏幕依然填充为红色
- 5
- 6 canvas.drawRect(new Rect(-100, -100, 0, 0), new Paint());//缩放了
- 7 canvas.scale(0.5f, 0.5f);
- 8 canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());
- 9
- 10 canvas.translate(200, 0);
- 11 canvas.rotate(30);
- 12 canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());//旋转了
- 13
- 14 canvas.translate(200, 0);
- 15 canvas.skew(.5f, .5f);//扭曲了
- 16 canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());
- 17 // canvas.setMatrix(matrix);//Matrix的使用在后面在是。
- 18 }
3)、Color类
①、Android系统中颜色的常用表示方法有以下3种:
(1)int color = Color.BLUE;
(2)int color = Color.argb(150,200,0,100);
(3)在xml文件中定义颜色;
②、在实际应用当中,我们常用的颜色有以下一些,其颜色常量及其表示的颜色如下所示:
Color.BLACK 黑色 Color.GREEN 绿色
Color.BLUE 蓝色 Color.LTGRAY 浅灰色
Color.CYAN 青绿色 Color.MAGENTA 红紫色
Color.DKGRAY 灰黑色 Color.RED 红色
Color.YELLOW 黄色 Color.TRANSPARENT 透明
Color.GRAY 灰色 Color.WHITE 白色
四、Bitmap 图像