我们都知道主题的指定实际上实在styles.xml文件中。现在用Android Studio建一个工程,styles.xml默认是这个样子的:
@color/colorPrimary
@color/colorPrimaryDark
@color/colorAccent
可以看到我们的主题默认继承了Theme.AppCompat。那么这个Theme.AppCompat到底是什么呢?就要从其他的三个系统基本主题说起
android:Theme
android:Theme.Holo
android:Theme.Material
是的,这三个主题就对应了上一节说的三种Android主题。android:Theme是所有主题的超级父类。所有的主题都是它继承或者间接继承来的。android:Theme.Holo从Api 11开始才可以使用。android:Theme.Material从Api 21开始可以使用。
如果我们要在不同版本的系统上用各自的主题,比如在4.0之下的系统用android:Theme,4.0至5.0的系统用Holo主题,5.0及之后的系统使用Material Design,那我们需要建不同的value-vX目录。在各自的目录中的style继承相应的系统主题。在运行是系统就会根据平台版本使用相应的主题。如果使用的主题没有找到,那么系统就会根据App指定的targetSdkVersion自动设置主题,假如设置的targetSdkVersion超过了系统的版本,系统就设置为支持的最高系统sdk版本的主题。
最后一句话怎么理解,举个例子,如果在我们在Api 24的sdk下进行开发,设置我们的应用targetSdkVersion=16,应用的资源目录下建立value-16,这是针对4.4以上平台的资源目录,在styles.xml中我们继承android:Theme.Material,这很明显是在5.0系统之上才能用的。虽然Android Studio会给出提示,但可以编译通过。现在我们把App放在一台4.4的机器上跑,这时系统是找不到android:Theme.Material这个主题的。那么系统就会看targtSdkVersion,发现是16,所以系统就会将App的主题设置为Holo的。如果我们其他的所有配置都不变,只把targetSdkVersion改成9,系统就会把App的主题设置为android:Theme的主题。这时如果把targetSdkVersion改成24,4.4的机器是不支持24的,那么出来的效果依然是android:Theme.Holo主题。