安卓开发入门之主题与样式必看知识点(翻译)

来源:互联网 发布:菜刀切到手 知乎 编辑:程序博客网 时间:2024/06/04 19:58


原文链接

http://blog.octo.com/en/android-themes-styles-a-real-architecture/

问题引入

当我们在AS(Android Studio)中创建新工程的时候,AS会为我们创建一个单一的style.xml文件,里面有AppTheme属性。由于这里是我们存放theme属性的公共地方,随着工程越大,AppTheme也会越大。
但是,有时候我们需要增加设备或者API级别的属性值。比如说,我们开发的app支持最小Sdk16,与此同时,我们需要在theme中使用windowTransluscentStatus属性。由于该属性从API19以后才有,当我们将在AppTheme中使用的时候会报错。如下图所示。


在安卓开发中,我们可以将一些资源文件放置在指定文件夹用于适应特定API。在刚才的例子中,我们可以创建一个名为res/values-v19/的文件加,里面放新的style.xml。这样,当我们的app在API19的设备上运行时,系统优先从使用该新文件而不是res/values中的文件。
好,回到theme。我们现在有两个简单的方案来解决刚才的问题。

方案1:
-从 res/values/styles.xml中复制AppTheme。
-粘贴到-v19中
-在-v19中新增属性
这样新属性就可以在API19及以上使用了。但是,最好不要这么做,因为以后维护起来将是一个坑,对,坑。以为以后一旦下要在base theme中添加新属性,还要复制一份到-v19中,而我们往往容易忘记这一步。
方案2:
-在res/values/styles.xml中创建BaseAppTheme
-同时让AppTheme继承BaseAppTheme
-在-v19文件中让AppTheme也继承BaseAppTheme
-新增属性
至此,假如我们想新增API属性,只需要修改BaseAppTheme,而不用担心来回复制,好极了!
values/styles.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <!-- Base application theme. -->    <style name="BaseAppTheme" parent="Theme.AppCompat.Light.NoActionBar">        <!-- Customize your theme here. -->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>        <item name="android:windowBackground">@color/windowBackground</item>    </style>    <style name="AppTheme" parent="BaseAppTheme"/></resources>
values-v19/styles.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <style name="AppTheme" parent="BaseAppTheme">        <item name="android:windowTranslucentStatus">true</item>    </style></resources>
更多的API级别
至此,本文的第一个问题已解决。现在,你得知API21有个新属性你想使用。于是,你如法炮制,创建了文件夹 res/values-v21/,新增文件styles.xml,新的AppTheme继承BaseAppTheme ,并且写下你想使用的新属性。
values-v21/styles.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <style name="AppTheme" parent="BaseAppTheme">        <item name="android:windowSharedElementEnterTransition">@android:animator/fade_in</item>    </style></resources>
现在让我们的app运行在Lollipop+(API21+),会发现状态栏(status bar)不再是transluscent !这是当然的啦。因为在API21+设备上面运行优先使用-v21文件,那么-v19文件就失效啦。
主题继承链
为了解决第二个问题,让我们重写主题。
values/styles.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <style name="AppTheme" parent="Base.V0.AppTheme"/>    <style name="Base.V0.AppTheme" parent="Theme.AppCompat.Light.NoActionBar">        <!-- Generic, non-specific attributes -->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>        <item name="android:windowBackground">@color/windowBackground</item>    </style></resources>
values-v19/styles.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <style name="AppTheme" parent="Base.V19.AppTheme"/>    <style name="Base.V19.AppTheme" parent="Base.V0.AppTheme">        <!-- API 19 specific attributes -->        <item name="android:windowTranslucentStatus">true</item>    </style></resources>
values-v21/styles.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <style name="AppTheme" parent="Base.V21.AppTheme"/>    <style name="Base.V21.AppTheme" parent="Base.V19.AppTheme">        <!-- API 21 specific attributes -->        <item name="android:windowSharedElementEnterTransition">@android:animator/fade_in</item>    </style></resources>

至此,第二个问题已解决。同样适用于style中,具体方法见原文。

原文链接

http://blog.octo.com/en/android-themes-styles-a-real-architecture/