概论:
- 说在前面的话
- 继承框架提供的布局
- 布局文件
- 构造方法
- 状态保存
1.说在前面的话
自定义组合控件还是蛮简单的,你不用measure,layout,draw,当然你想的话也可以在组合控件上做这些操作的,不过大多数时候是没有必要的。组合控件的自定义属性和自定义view完全一样,这里比较难的是状态保存,因为一个页面可以有很多个你自定义的组合控件,但是系统的状态保存是依赖viewID的,所以你不能让ViewGroup来管理你的控件状态,只能自己管理了。当然,你也可能不需要状态保存,那就很简单了。
下面说说需要经历的步骤吧:
- 让自定义的组合控件继承框架提供的布局,如
LinearLayout
,RelativeLayout
等。 - 把你组合控件里面的子控件放到一个布局文件中,然后在组合控件的构造方法中加载进来。
- 采用
merge
作为你布局文件的根,这样可以减少嵌套层次。 - 接下来是比较难的状态保存。
- 自定义属性,这个和自定义view一样。
2.继承框架提供的布局
|
|
3.布局文件
样例如下:
|
|
4.构造方法
|
|
5.状态保存
前面说过了,由于你控件可能会在一个页面出现多次,所以viewID会重复,这样系统就没办法帮你管理状态了。所以如果你要管理children的状态,就必须亲自动手了,而不是让children自己管理自己的状态。
要想管理children的状态,你必须要知道ViewGroup的四个状态管理的方法,他们是:
|
|
A ViewGroup uses dispatchSaveInstanceState to first save its own state by calling super (view’s) dispatchSaveInstanceState, which in turn triggers onSaveInstanceState on itself and then calls the dispatchSaveInstanceState for each of its children. If the children are plain views and not ViewGroups, this will result in having their onSaveInstanceState called. Listing 2-12 presents the pseudo code for how these key methods are meshed together.
|
|
技巧在于dispatchFreezeSelfOnly
,这个ViewGroup方法只是简单的保存了ViewGroup的状态,这同样也发生在对应的恢复dispatchThawSelfOnly
上。所以你可以重写ViewGroup的方法来阻止children自己管理状态。如下所示:
|
|
接下来就需要ViewGroup在onSaveInstanceState
和 onRestoreInstanceState
中管理children的状态了,实例代码如下:
|
|
其实这就相当于把整个组合控件当成一个View来管理