【译】Android Styling 3: 使用主题和主题属性的优势
2020/6/20 23:26:24
本文主要是介绍【译】Android Styling 3: 使用主题和主题属性的优势,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
原文:Android Styling: Prefer Theme Attributes
作者:Nick Butcher
译者:Fly_with24
题图来自 Virginia Poltrack
Android Styling 系列的前几篇文章中,我们研究了主题和样式之间的区别,以及使用主题和常用的主题属性的优势
这使我们创建更少地布局和样式,隔离主题内的变化。在实践中,您应 始终* (此处有星号,后文解释) 通过主题属性来控制颜色
Always refer to colors via theme attributes*
传统做法是这样的
<!-- Copyright 2019 Google LLC. SPDX-License-Identifier: Apache-2.0 --> <View … android:background="@color/white"/> 复制代码
事实上,您应该引用主题属性,它允许您通过主题来控制颜色,例如,在暗黑主题下提供不同的颜色
<!-- Copyright 2019 Google LLC. SPDX-License-Identifier: Apache-2.0 --> <View … android:background="?attr/colorSurface"/> 复制代码
即使您当前不支持其他主题(什么?没有暗黑主题?),我还是建议您采用这种方法,因为这样会使采用主题更加容易
Qualified Color?
您可以在不同的配置下使用不同的色值(例如,@color/foo
在 res/values/colors.xml
和 res/values-night/colors.xml
下均有定义),但我建议您使用主题属性
颜色层级的变化是您必须给颜色一个语义明确的名字,例如您可能不会命名一个颜色为 @color/white
并在暗黑主题内提供一个变体(这会很奇怪并且混乱)。取而代之的是您可能会使用一个语义明确的名字,例如 @color/background
。但这样做的问题是它既代表了语义又代表了色值,它没有展示出使用有能够跟随主题变化的能力
使用 @colors
会导致你创建出更多的颜色。如果您在某些场景下需要一个新的语义值,但该色值之前却定义过(例如,你需要一个和 background 相同色值的颜色,但是会将其命名为其他名字),您需要在 colors 文件中再创建一条
通过使用主题属性,我们将色值与颜色的语义名字分离,使调用更加清晰(使用 ?attr/
语句调用),颜色将随主题而变化。将颜色声明保持为字面值,使您定义了一个「调色板」,您可以在主题层级上进行更改,从而使 color 文件较小且更易维护
Define a palette of colors used by your app and vary them at the theme level
定义 app 的调色板,并在主题层级进行更改
这种方法的另一个好处是,引用这些颜色的 layouts/styles 变得可复用。 由于主题可以覆盖或变化,因此间接表示您无需创建其他布局或样式就可以仅更改某些颜色——您可以将相同的布局用于不同的主题
Always?
前文的 「始终* 通过主题属性来控制颜色」 中的(always)带有星号,因为在某些情况下,您很明确不想按主题更改颜色。例如 Material Design guidelines 中指出有些场景您可能希望在浅色和深色主题使用相同的「品牌色」
在这种特殊场景下,直接引用颜色资源也是可以的
<!-- Copyright 2019 Google LLC. SPDX-License-Identifier: Apache-2.0 --> <FloatingActionButton … app:backgroundTint="@color/owl_pink_500"/> 复制代码
State of the art
不使用主题属性的另一种情况是使用 ColorStateList
<!-- Copyright 2019 Google LLC. SPDX-License-Identifier: Apache-2.0 --> <View … android:background="@color/primary_20"/> 复制代码
如果 primary_20
是一个 ColorStateList
并且它本身通过主题属性引用色值,则这可能是有效的(请参见下文)。 虽然通常用于在不同状态(按下,禁用等)下提供不同的颜色,但 ColorStateLists
具有另一种可用于主题化的功能。 它可以帮你为一个颜色设置透明度
<!-- Copyright 2019 Google LLC. SPDX-License-Identifier: Apache-2.0 --> <selector … <item android:alpha="0.20" android:color="?attr/colorPrimary" /> </selector> 复制代码
这种单项 ColorStateList
(即,仅提供一种默认颜色,所有状态都一样)有助于减少需要维护的颜色资源数量。它不是通过手动的创建一个新的颜色资源来为 app 的主色设置透明度(每个配置),取而代之的是通过当前主题 colorPrimary
来处理。如果您的 主色 发生了变化,则只需要在一个地方进行更新,而无需跟踪对其进行了调整的所有实例
尽管有用,但要注意此技术的一些注意事项
- 如果指定的颜色也具有透明度,则会将 alpha 进行组合,例如 50% 的透明度应用与 50% 透明的白色会得到 25% 的白色
出于此原因,最好将主题颜色指定为完全不透明,并使用
ColorStateLists
修改其 Alpha
-
alpha 组件是 API 23 后引入的,因此您的 app min sdk 版本比这个低,请确保使用兼容的 AppCompatResources.getColorStateList 并一直使用
android:alpha
命名空间,不要使用app:alpha
命名空间 -
将普通的颜色作为 drawable
View 的 background 属性 需要一个 drawable,我们使用普通的颜色设置 background 是可以的,其内部会把 color 转换为 ColorDrawable
,然而 ColorStateList
是无法转换为 Drawable 的(直到 API 29 ColorStateListDrawable 的出现解决了这一问题)。我们可以曲线救国解决此限制。
Enforcement
因此,您应该使用主题属性和 ColorStateList
,但是如何在整个代码库或团队中实施呢? 您可以在 code review 时关注,但这并不是个好办法。 更好的方法是依靠工具来解决此问题。这篇文章介绍了通过 lint 检查对不符合规范的用法给出更好的建议。文章在这
Be Indirect
使用主题属性和 ColorStateList
可以将颜色与主题分离,可以使布局和样式更加灵活,方便复用用并保持代码库精简和可维护性
感谢 Florina Muntenescu 和 Chris Banes
译文完
关于我
我是 Flywith24
-
掘金
-
简书
-
Github
这篇关于【译】Android Styling 3: 使用主题和主题属性的优势的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-01-18android.permission.read_media_video
- 2024-01-18android_getaddrinfo failed eai_nodata
- 2024-01-18androidmo
- 2024-01-15Android下三种离屏渲染技术
- 2024-01-09Android 蓝牙使用
- 2024-01-06Android对接华为AI - 文本识别
- 2023-11-15代码安全之代码混淆及加固(Android)
- 2023-11-10简述Android语音播报TTS
- 2023-11-06Android WiFi工具类
- 2023-07-22Android开发未来的出路