这是为不同版本设置不同值/样式的正确方法吗

问题描述 投票:0回答:7
Android Studio 2.1 preview 3

这只是一个问题,因为我很困惑,因为我在这样做时看到了很多替代方案。

我创建了一个新的android项目,我的Activity扩展了AppCompatActivity

public class MainActivity extends AppCompatActivity {

我希望在运行 21 及以上的设备上拥有

transparent statusbar

所以在我的

values/styles
我有以下内容

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" 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>
    </style>
</resources>

在我的

values-21/styles
中我有以下内容

<resources>
    <style name="AppTheme" 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>

        <!-- Make the statusbar transparent -->
        <item name="android:windowTranslucentStatus">true</item>
    </style>
</resources>

我的清单我选择主题

android:theme="@style/AppTheme"

只是一些问题

  1. 这是正确的方法,还是有更好的方法?
  2. values-21/styles
    会继承
    values/styles
    中的所有颜色吗,所以我必须重复这个?
android
7个回答
43
投票

这是正确的方法。我可以建议你更好地组织你的风格吗?

值/styles.xml

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="CommonTheme">

    </style>

    <style name="CommonTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

values-v21/styles.xml

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="CommonTheme">
        <!-- All customization of the theme for this version -->
        <item name="android:windowTranslucentStatus">true</item>
    </style>
</resources>

因此您无需为每个 api 级别重复样式的通用值。


13
投票

我会尝试回答它并提供一些参考

保持兼容性

为了避免重复代码,请在 res/values/ 中定义样式, 修改 res/values-v21/ 中新 API 的样式,并使用 style 继承,在 res/values/ 中定义基本样式并继承自 那些在 res/values-v21/

因此,您应该尝试使用样式继承来避免不同文件夹

style.xml
res/values/
中的
res/values-v21/
中出现代码重复。

风格传承

如果您想继承自己定义的样式,您可以 不必使用父属性。相反,只需添加名称前缀即可 将您想要继承的样式命名为新样式的名称, 用句点分隔。

如果您想继承自己定义的样式,您可以跳过添加

parent
属性并使用点或句点符号继承它。

使用此功能,您可以在

BaseTheme
中定义具有不同颜色的基本主题
res/values/
,并从其继承为
BaseTheme.StyledStatusBar
,而无需指定父属性。

<resources>
    <style name="BaseTheme.StyledStatusBar"></style>

    <!-- Base application theme. -->
    <style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

values-21/
中,将项目
android:windowTranslucentStatus
添加到
BaseTheme.StyledStatusBar

<resources>
    <style name="BaseTheme.StyledStatusBar">
        <item name="android:windowTranslucentStatus">true</item>
    </style>
</resources>

在清单中,选择主题

android:theme="@style/BaseTheme.StyledStatusBar"

6
投票

1)这是正确的方法吗?还是有更好的方法吗?

是的。这是针对不同 API 版本使用不同值的正确/推荐方法。

2)values21/styles 会继承values/styles 中的所有颜色吗,所以我必须重复这个?

我不确定我是否完全理解这个问题。您展示的两种样式都将从

Theme.AppCompat.Light.NoActionBar
继承,因此您的颜色应该再次声明,但我将提供两种更好的选择:

替代方案1,好一点:

使用两者通用的基本主题。要查看它的代码,请检查@mimmo-grottoli 答案。

替代方案2,更好:

如果两个主题唯一的不同是 KitKat(API 级别 19)中引入的

android:windowTranslucentStatus
,您可以将它们全部放在值/样式中的同一主题中,如下所示:

<resources>
    <style name="AppTheme" 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>

        <!-- Make the statusbar transparent -->
        <item name="android:windowTranslucentStatus">true</item>
    </style>
</resources>

Android 框架会忽略它无法识别的 XML 参数。这意味着在 JellyBean 或 ICS 上,设备在正确应用颜色时将忽略

windowTranslucentStatus
,而在 KitKat 及更高版本中,它将正确应用
windowTranslucentStatus

这个技巧对于 Android 中的所有 XML(甚至布局)都有效,IDE 可能会向您提供有关 API 级别的警告,但在 XML 中它们始终可以安全使用。


2
投票

当您的应用程序在特定版本的 Android 上运行时,会创建不同的值/样式文件夹以提供独特的样式。

所以,是的,你说新版本继承旧版本是对的。在最新版本的样式中添加项目时,您可以使最新版本保持最新的 API。

总而言之,您的方式是非常常见的方式,这是一种有组织且干净的方式来保持应用程序更新。


2
投票
  1. 这是正确的方法,还是有更好的方法?

是的。这是为不同的 API 版本设置不同的值的正确方法。

values-21/styles 是否会继承 value/styles 中的所有颜色,所以我必须重复此操作?

是的


0
投票

从技术上讲,

<item name="android:windowTranslucentStatus">true</item>
不会为您提供完全透明的状态栏。

如果你想让它完全透明,你可以使用

<item name="android:statusBarColor">@android:color/transparent</item>


0
投票

您还可以为每个选项指定

targetApi

<item name="android:dialogCornerRadius" tools:targetApi="p">16dp</item>

这种方法比定义基本样式并继承更简洁

© www.soinside.com 2019 - 2024. All rights reserved.