2018-07-13

Android 自定义View

前言

首先我们先了解一下,什么叫view?Android官方文档对View的解释是这样的:表示用户界面组件的基本构建块,视图占据屏幕上的矩形区域,负责绘图和事件处理。以上可以看出view是程序与用户之间进行交互的桥梁。view的形状,大小,表现形式多种多样,所有就会发现Android系统能提供给我们的有时候并不能满足我们的需求,所以就会需要程序员去自定义view。

下面我就介绍以下如何自定义view,我将自定义View基础、自定义View绘制流程、事件分发机制这三个方面来介绍。

一 自定义View基础

1.1 坐标系

屏幕坐标系与数学坐标系的差异

1.1.1 屏幕坐标系

1.1.1 view的坐标系

注意:View的坐标系都是相对于父控件而言。

1.2 颜色

三原色

1.3 分类

根据用途来分,一般将自定义分为两种:即自定义控件和自定义布局.

1.4 自定义属性

自定义属性步骤

二 自定义view绘制流程

2.1 绘制流程

2.2 相关函数介绍

2.2.1 构造函数

一个参的构造,一般在java代码中直接new一个View时调用。

两个参的构造,一般在Layout文件中使用的时候调用,关于它的所有属性(包括自定义属性)都会通过attrs传递进来。

三个参数的构造,第三个参数是默认的Style,这里的默认的Style是指它在当前Application或Activity所用的Theme中的默认Style。

四个参数的构造,第四个参数是指向一个style的ID,但是是在defStyleAttr为0,或者defStyle不为0,但theme没有为defStyleAttr属性赋值时起作用。

2.2.2 测量view的大小函数-onMeasure()

作用:测量View的大小,并从widthMeasureSpec 和 heightMeasureSpec中取出宽高的相关数据,它们其实不是宽和高, 而是由宽、高和各自方向上对应的测量模式来合成的一个值。

测量模式:

三种测量模式,通过MeasureSpec.getMode()得到测量模式, Measure.getSize()得到测量数值。

2.2.3 确定view的大小函数-onSizeChanged()

作用:确定View大小,在视图大小发生改变时调用,它有四个参数,分别为宽度,高度,上一次宽度,上一次高度。

2.2.4 确定子view的布局-onLayout()

作用:它用于确定子View的位置,在自定义ViewGroup中会用到,他调用的是子View的layout函数。它有四个参数如下:

2.2.5 绘制view的函数-onDraw()

作用:绘制内容,使用canvas进行绘图.

三 事件分发机制

为什么要有事件分发机制?

有时候界面上的view并不是很规则整齐的排列在一起,View之间是有可能重叠在一起的,当我们点击的地方有多个View响应时,这个点击事件应该分发给谁?为了解决这一部分就有了事件分发机制。

3.1 事件分发核心函数

以上三个方法都有一个boolean类型的返回值,通过返回true或者false来控制事件的流程.

3.2 事件分发流程

责任链模式,即如果自己能处理就拦截下来自己处理,如果不能处理或者不确定就交给责任链中的下一个对象。如下图:

3.2.1 事件分发机制流程详解

事件传递顺序:

注意:事件传递过程先执行分发,再执行拦截,事件传递返回 true,表示事件被拦截,交给自己的onTouchEvent处理;false,表示不拦截,向下传递。

事件处理顺序:

注意:事件的处理都要进过onTouchEvent,事件处理返回true,表示事件自己处理,false,表示向上传递。

3.2.2 事件分发机制流程概括

(1)事件如果被消费,就意味着事件传递消息被终止。

(2)如果事件一直没有被消费就会传递给activity,如果activity也不需要就会被抛弃。

(3)判断事件是否被消费是根据返回值,并不是根据你是否使用了该事件。

Android 事件分发,一般可以理解为:

(a)ViewGroup对点击事件的分发机制。

(b)View对点击事件的分发机制。

3.3 MotionEvent对象

根据面向对象的思想,事件被封装成MotionEvent对象。

对于单指触控来说,一次简单的交互流程是:

3.4 ViewGroup的事件分发

注意:ViewGroup的事件分发不仅要考虑自身,还要考虑子View.

ViewGroup的分发流程:

3.4.1 子view存在重合点时的处理

情况一:

只有View1可以点击时,该点击事件分配给View1

情况二:

只有View2可以点击时,该点击事件分配给View2

情况三:

View1、View2均可点击时,该点击事件分配给View2,如果View2将事件消费掉了,则View1将接收不到.

3.4.2 view的可点击情况分类:

onClick

onLongClick

onContextClick

android:clickable=“true”

button ,ImageButton,CheckBox默认是可点击的。

3.5 view的事件分发流程

3.6 总结

以上只是个人对自定义view的理解.有不对的地方,欢迎指正!

你可能感兴趣的:(2018-07-13)