上一讲我们介绍了安卓View的各种状态,目前安卓的View一共是10个状态。这些状态相当于是从不同的角度来描述一个View的情况,所以这些状态并不是互斥的,比如,一个View可以同时处在enabled和pressed两个状态。我们把一个View在某一时刻具备的状态的集合称之为状态集。
那么,如果这些都不互斥,那么一个View的一共可以有多少个状态集呢?对,就是210=1024种状态。
于是,View中就有这么一段代码:
final int NUM_BITS = VIEW_STATE_IDS.length / 2;
VIEW_STATE_SETS = new int[1 << NUM_BITS][];
for (int i = 0; i < VIEW_STATE_SETS.length; i++) {
int numBits = Integer.bitCount(i);
int[] set = new int[numBits];
int pos = 0;
for (int j = 0; j < orderedIds.length; j += 2) {
if ((i & orderedIds[j+1]) != 0) {
set[pos++] = orderedIds[j];
}
}
VIEW_STATE_SETS[i] = set;
}
VIEW_STATE_IDS上一讲有介绍过,VIEW_STATE_IDS存放的是状态的标记位和属性值,所以VIEW_STATE_IDS.length的值是20,NUM_BITS的值就是10。VIEW_STATE_SETS就是定义的状态集的合集,它的大小正是1024。
接下来的代码就是在构造这1024个状态集。
确实有点夸张了,状态集太多了,实际上也根本不可能存在那么多的状态集。
于是,View里面最终选定了27个状态集,它们是:
EMPTY_STATE_SET
WINDOW_FOCUSED_STATE_SET
SELECTED_WINDOW_FOCUSED_STATE_SET
FOCUSED_STATE_SET
FOCUSED_WINDOW_FOCUSED_STATE_SET
FOCUSED_SELECTED_STATE_SET
FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET
ENABLED_STATE_SET
ENABLED_WINDOW_FOCUSED_STATE_SET
ENABLED_SELECTED_STATE_SET
ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET
ENABLED_FOCUSED_STATE_SET
ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET
ENABLED_FOCUSED_SELECTED_STATE_SET
ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET
PRESSED_STATE_SET
PRESSED_WINDOW_FOCUSED_STATE_SET
PRESSED_SELECTED_STATE_SET
PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET
PRESSED_FOCUSED_STATE_SET
PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET
PRESSED_FOCUSED_SELECTED_STATE_SET
PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET
PRESSED_ENABLED_STATE_SET
PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET
PRESSED_ENABLED_SELECTED_STATE_SET
PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET
也就是说,这又上述状态集里的状态组合是有意义的。再换句话说,如果用selector实现不同的状态,最多可以有27种状态。
好了,到目前为止,我们已经介绍了状态系统逻辑层面的设计。那用户是如何看到View的界面的变化呢?是通过Drawable的状态变化。那View的状态和Drawable的状态是怎么连接的呢,是通过一个叫做StateSet的类。
下一讲,我们就重点来讲一讲StateSet。