最近项目申请整理谷歌商店的推荐位,谷歌审核人员提出Theme过时,要求对于App使用Theme.AppCompat或Theme.Material及其派生的主题,而对于这方面的说明,网上基本都是安卓原生的设置方式,用在unity上并不管用,折腾了我一天,终于理清楚了unity在安卓平台的theme设置方式,这里简单做一个记录。
安卓Theme的简单说明
我们都知道,安卓到现在已经出到了安卓10,在这么多代的发展中,也从一开始完全没有设计到现在有专门的theme,一共经历了几个大阶段,使用形式可以看下表:
安卓版本/来源 | 可用API版本 | 样式形式 | 样式举例 |
---|---|---|---|
Android 1.0 | level 1 | Theme.XXXX | Theme.Black.NoTitleBar.Fullscreen |
Android 4.0 | level 14 | Theme.Holo.XXXX | Theme.Holo.Light |
Android 5.0 | level 21 | Theme.Material.XXXX | Theme.Material.Light |
compat支持库 | 所有level,引入即可用 | Theme.AppCompat.XXXX | Theme.AppCompat.Light |
除了compat支持库之外,其他三种只要在对应的版本下,即可直接调用,一般情况下高版本自动向下兼容使用低版本的Theme,比如当前是Android 版本是 8.0,那么直接在使用Theme.XXXX
和Theme.Holo.XXXX
都是没有问题的。
但是level 21以下的版本想要使用Material风格的Theme就做不到了,这个时候谷歌推出了theme兼容库,只要引入了对应的库,即可在低版本的android应用中使用新的theme,常用的库有v4.compat、v7.compat库等,具体引入方式这里不展开讲了,算是基础知识,如果不太明白,可以看下面的链接:
关于安卓支持库,谷歌现在大力推进androidx支持库,老的android库正在慢慢淘汰,详细说明可以看这里:安卓支持库
关于安卓原生Theme的详细说明,可以阅读谷歌安卓官方的说明:样式和主题背景。
Unity使用安卓Theme的设置
回到Unity,Unity里要想进行原生Theme的配置,首先需要使用gradle方式进行build,在2017.4之后的新版本中,Unity默认都会使用gradle模式进行配置,但是具体的theme配置,还要通过AndroidManifest.xml
文件来进行配置。
首先要进入Build>Build Setting> Player Setting> Publish Settings\Build
界面,确认Build System
选项是gradle:
然后我们打开Unity的安装文件夹,比如我安装在C:\Program Files\Unity\2017.4.40c1\
中,进入这个文件夹,继续深入,如果安装了Android插件支持,进入Editor\Data\PlaybackEngines\AndroidPlayer
,文件目录如下图所示:
这个文件夹下存放了当前所有的安卓支持工具(不包括支持库),比如Tools文件夹下有gradle,Variations下有unity的编译库等等,有兴趣的可以逐个翻看,不过我们现在要进入的是Apk文件夹,打开文件夹,可以看到这样的内容:
做过一段时间安卓版本的同学一定会很眼熟,没错,这两个文件就是跟安卓原生项目里对应的AndroidManifest.xml
文件和res文件,再打开res文件夹,如下:
Unity的Theme配置方式
说到unity中的theme配置,首先还是要以官方的文件为准:Android Themes in Unity
简单来说,其实Unity早在2015年就做好了这方面的支持,所以在安装文件夹下的styles中就已经根据版本配置了对应的theme了,我们也可以很容易地在上面的几个文件夹里看到,unity设定了UnityThemeSelector
和UnityThemeSelector.Translucent
两种主题,只要直接使用这两者,unity就会根据api版本自动选择合适的theme:
<!-- values文件夹下的styles.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="UnityThemeSelector" parent="BaseUnityTheme">
<item name="android:windowBackground">@android:color/black</item>
</style>
<style name="BaseUnityTheme" parent="android:Theme.Light.NoTitleBar.Fullscreen">
</style>
<style name="UnityThemeSelector.Translucent" parent="@style/UnityThemeSelector">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
</resources>
<!-- values-v14文件夹下的styles.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="BaseUnityTheme" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen">
</style>
</resources>
<!-- values-v21文件夹下的styles.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="BaseUnityTheme" parent="android:Theme.Material.Light.NoActionBar.Fullscreen">
</style>
</resources>
当然了,这只是Unity自己的theme,如果我们需要自己配置的theme怎么办呢?这里就要注意unity的载入机制了。
- 这里AndroidManifest文件的机制是,当unity里的
Plugins/Android
文件夹下没有AndroidManifest时,会默认使用这里的文件,如果有,那么这里的文件会被无效化,而直接使用项目中对应的文件。 - 而对于values里的styles文件,Unity的处理方式就很有意思了,Unity会先对项目中定义的
styles.xml
文件进行处理,然后将Apk/res下的styles.xml追加到项目中的styles之后——注意这个顺序,也就是说,安装文件夹下的styles.xml是可以引用项目中定义的style的,但反过来却不行。
特别需要注意的点
以上基本就是unity配置Theme的特点了,具体应用根据需求来即可,但是——
如果有的同学就是想要Theme.AppCompat
风格怎么办?
肯定有的同学就会说了:跟安卓原生一样使用即可。
但是这样是不行的!!!
即使你所有的依赖库都正确设置了,Unity还是会报这样的错:
AAPT: error: 'android:Theme.AppCompat.Light' is incompatible with attribute theme (attr) reference.
所以老老实实使用Theme.Material风格吧。