安卓系统的造型:共同的主题属性

评论 8 浏览 0 2020-02-04

在本系列关于Android风格设计的前一篇文章中,我们探讨了主题和风格之间的区别,以及主题如何让你写出更灵活的风格和布局,从而隔离变化。

Android造型。主题与风格 安卓风格系统提供了一种强大的方式来指定你的应用程序的视觉设计,但它可能很容易被滥用…

具体而言,我们建议使用主题属性来为资源提供一个指示点,这样您就可以改变它们(例如,在黑暗主题中)。也就是说,如果你发现自己在布局或样式中写了一个直接的资源引用(或者更糟糕的是,一个硬编码的值😱),请考虑你是否应该使用主题属性来代替。

<!-- Copyright 2019 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 -->
<ConstraintLayout ...
-  android:foreground="@drawable/some_ripple"
-  android:background="@color/blue" />
+  android:foreground="?attr/selectableItemBackground"
+  android:background="?attr/colorPrimarySurface" />

但是有哪些主题属性可供使用呢?这篇文章强调了你应该知道的常见属性;那些来自Material、AppCompat或平台的属性。这并不是一个完整的列表(为此我建议浏览下面链接的attrs文件,其中定义了这些属性),但这些是我经常使用的属性。

色泽

这些颜色中有许多来自材料颜色系统,该系统为颜色定义了语义名称,您可以在整个应用程序中使用这些颜色(作为主题attrs实现的)。

  • ?attr/colorPrimary 应用程序的主要品牌颜色。
  • ?attr/colorSecondary 应用程序的次要品牌颜色,通常是对主要品牌颜色的一个明亮的补充。
  • ?attr/colorOn[Primary, Secondary, Surface etc] 一种与命名的颜色形成对比的颜色。
  • ?attr/color[Primary, Secondary]Variant 给定颜色的另一个阴影。
  • ?attr/colorSurface 一种用于组件表面的颜色,如卡片、薄片和菜单。
  • ?android:attr/colorBackground 画面的背景。
  • ?attr/colorPrimarySurface在浅色主题的colorPrimary之间切换,colorSurface在深色主题的colorSurface之间切换。
  • ?attr/colorError 一种用于显示错误的颜色。

其他方便的颜色。

  • ?attr/colorControlNormal 在正常状态下应用于图标/控件的颜色。
  • ?attr/colorControlActivated 应用于图标/控件在其激活状态(如勾选)下的颜色。
  • ?attr/colorControlHighlight 应用于控制高亮部分的颜色(如涟漪、列表选择器)。
  • ?android:attr/textColorPrimary 最显眼的文字颜色。
  • ?android:attr/textColorSecondary次要的文本颜色。

肢体语言

  • ?attr/listPreferredItemHeight 列表项的标准(最小)高度。
  • ?attr/actionBarSize 工具栏的高度。

可画图的东西

  • ?attr/selectableItemBackground 一个用于交互式项目的波纹/高光(对前景也很方便!!)。
  • ?attr/selectableItemBackgroundBorderless 一个不受约束的波纹。
  • ?attr/dividerVertical 一个可以作为视觉元素之间的垂直分隔线的可画性。
  • ?attr/dividerHorizontal 一个可以作为视觉元素之间的水平分割线的可画性。

文本的出现

Material 定义了一个字体比例—一组离散的文本样式,你应该在整个应用程序中使用,每一个都提供了作为一个主题属性,可以设置为textAppearance。请查看材料类型比例生成器,以帮助生成不同字体的比例。

  • ?attr/textAppearanceHeadline1默认为浅色的96sp文本。
  • ?attr/textAppearanceHeadline2默认为浅色的60sp文本。
  • ?attr/textAppearanceHeadline3默认为普通的48sp文本。
  • ?attr/textAppearanceHeadline4默认为普通的34sp文本。
  • ?attr/textAppearanceHeadline5默认为普通的24sp文本。
  • ?attr/textAppearanceHeadline6默认为中等的20sp的文本。
  • ?attr/textAppearanceSubtitle1默认为普通的16sp文本。
  • ?attr/textAppearanceSubtitle2默认为中等的14sp文本。
  • ?attr/textAppearanceBody1默认为普通的16sp文本。
  • ?attr/textAppearanceBody2默认为普通的14sp文本。
  • ?attr/textAppearanceCaption默认为普通的12sp文本。
  • ?attr/textAppearanceButton默认为中号全大写14sp文本。
  • ?attr/textAppearanceOverline默认为普通的全部大写的10sp文本。

形体

Material 采用了形状系统,该系统被实现为小型、中型和大型组件的主题attr。请注意,如果您要在自定义组件上设置形状外观,您可能希望使用MaterialShapeDrawable,因为它的背景能够理解并实现形状。

  • ?attr/shapeAppearanceSmallComponent用于按钮、筹码、文本字段等。默认为圆角的4dp角。
  • ?attr/shapeAppearanceMediumComponent用于卡片、对话框、日期选择器等。默认为圆角的4dp角。
  • ?attr/shapeAppearanceLargeComponent用于底层表等。默认为圆角的0dp角(即方形!)。

按钮的样式

这可能看起来超级具体,但材料定义了三种类型的按钮。包含文本轮廓。MDC提供了主题属性,你可以用它来设置一个MaterialButtonstyle

  • ?attr/materialButtonStyle默认为包含(或直接省略样式)。
  • ?attr/borderlessButtonStyle为一个文本风格的按钮。
  • ?attr/materialButtonOutlinedStyle为概述的风格。

浮点计时器

  • ?android:attr/disabledAlpha 小工具的默认禁用阿尔法。
  • ?android:attr/primaryContentAlpha 应用在前景元素上的alpha。
  • ?android:attr/secondaryContentAlpha 应用于次要元素的阿尔法。

应用程序与安卓命名空间的关系

你可能已经注意到,有些属性是用?android:attr/foo来引用的,有些则是用?attr/bar。这是因为有些属性是由Android平台定义的,因此你需要用android部分来引用它们的命名空间(就像布局中的视图属性:android:id)。那些没有来自静态库(即AppCompat或MDC)的元素被编译到你的应用程序中,所以不需要命名空间(类似于你在布局中使用app:baz的方式)。有些元素在平台和库中都有的定义,例如colorPrimary。在这些情况下,请选择非平台版本,因为这可以在所有的API级别上使用,即它们’在库中被重复,正是为了回传它们。在这些情况下,我在上面列出了非平台版本。

prefer non-platform attributes which can be used on all API levels

更多的资源

关于可使用的主题属性的完整列表,请到真理之源去。

材料设计的组成部分。

自己动手做吧

有时没有一个主题属性,它可以抽象出你想按主题变化的东西。不用担心… 创建你自己的!这里有一个来自Google I/O应用的例子,它在两个屏幕上显示了一个会议的列表。

两块屏幕上列出了会议的内容

它们大体上是相似的,但左边的屏幕必须为粘性时间标题留出空间,而右边的屏幕则没有。我们通过在主题属性后面抽象出对齐项目的位置来实现这一点,这样我们就可以根据主题来改变它们,并在两个不同的屏幕上使用相同的布局。

1.在attrs.xml中定义主题属性。

<!-- Copyright 2019 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 -->
<attr name="sessionListKeyline" format="dimension" />

2.在不同的主题中提供不同的价值

<!-- Copyright 2019 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 -->
<style name="Theme.IOSched.Schedule">
  …
  <item name="sessionListKeyline">72dp</item>
</style>

<style name="Theme.IOSched.Speaker">
  …
  <item name="sessionListKeyline">16dp</item>
</style>

3.使用主题attr在屏幕上使用的布局(各使用上述主题之一)。

<!-- Copyright 2019 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 -->
<Guideline …
  app:layout_constraintGuide_begin="?attr/sessionListKeyline" />

问题(标记)的一切

了解哪些主题属性是可用的,使你在编写你的布局、样式或可画性时能够使用它们。使用主题属性使得支持主题化(如黑暗主题)和编写更灵活、可维护的代码更加容易。关于这方面的深入研究,请加入我们本系列的下一篇文章。

Android的风格设计。首选主题属性 主题属性的所有内容

最后更新2022-11-02
16 个评论
#1 Rlogical Techsoft.Pvt.Ltd 2020-02-05

惊人的帖子。谢谢你与我们分享。这篇文章对我们的应用程序设计者和开发者真的很有帮助,信息量很大。

#2 Adib Faramarzi 2020-02-05

一个重要的注意点是,千万不要在可绘制文件中使用主题属性(比如avd中的? colorPrimary),因为它可能会破坏较低的API上的东西。

对于这些情况,最好是定义多个具有特定名称的drawqble文件(如橙色而不是主要的),并使用它们来区分主题属性。

Nick Butcher 2020-02-12

VectorDrawables实际上支持所有API级别的主题属性,这要感谢Jetpack库。你是对的,不幸的是objectAnimators在AnimatedVectorDrawables不支持主题属性,所以你必须使用颜色资源 :(

#3 Rashika Dubey 2022-06-14

研究安卓系统造型的惊人资源。

#4 José Luis Crisostomo Sánchez 2021-08-11

是否有可能在xml元素中添加@deprecated?

我知道我们将在某个时候摆脱xml文件,但我找不到一种方法来为诸如颜色这样的资源添加一个被废弃的标签。

#5 Daniel Gómez Rico 2020-05-14

嗨,Nick,首先感谢你的介绍,其次,是否有任何禁用状态的属性?

我的意思是,有主要的和次要的,但我找不到类似primaryDisabled或secondaryDisabled的东西,或者其他每个组件都提到禁用状态颜色的东西。

我应该通过直接使用颜色来设置吗?

Nick Butcher 2020-05-19

对于不同的状态,我们倾向于对主题颜色应用一个alpha。请看这些来自MDC的例子(这些例子本身可以组合成一个ColorStateList)。

https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/color/res/color

Daniel Gómez Rico 2020-05-14

或者可以创建一个自定义主题属性,并在所有地方使用它?

#6 Henning Bunk 2020-04-03

了不起的文章,非常感谢。在我读这些文章之前,这对我来说是相当混乱的。

我喜欢你在 "自己动手 "一章中举的例子。但不是缺少一个行动点吗?我猜你将不得不把不同的主题应用到你的ViewGroups或Activities中。

Nick Butcher 2020-04-06

说得好,我澄清了这段文字。每个屏幕在其各自的Activity上使用不同的主题。

#7 Igor Ganapolsky 2020-03-16

`?attr/color…`和东西的问题是,Android Studio不’在编辑器的一侧显示这些颜色的预览。直接使用@color/mycolor更方便,这样我们就可以在编辑器中实时预览这些颜色。

#8 anup kunwar 2020-02-28

你能不能解释一下,使用android:background="?attr/colorPrimarySurface "如何比使用android:background="@color/myPrimarySurfaceColor "更好?

Henning Bunk 2020-04-03

请确保阅读本系列中的第一篇文章,该文章在顶部有链接。

#9 Rlogical Techsoft.Pvt.Ltd 2020-02-05

惊人的帖子。谢谢你与我们分享。这篇文章对我们的应用程序设计者和开发者真的很有帮助,信息量很大。

#10 Adib Faramarzi 2020-02-05

一个重要的注意点是,永远不要在可绘制文件中使用主题属性(比如avd中的? colorPrimary),因为它可能会破坏较低API上的东西。

对于这些情况,最好是定义多个具有特定名称的drawqble文件(如橙色而不是主要的),并使用它们来区分主题属性。

Nick Butcher 2020-02-12

VectorDrawables实际上支持所有API级别的主题属性,这要感谢Jetpack库。你是对的,不幸的是objectAnimators在AnimatedVectorDrawables不支持主题属性,所以你必须使用颜色资源 :(

#11 Rashika Dubey 2022-06-14

研究安卓系统造型的惊人资源。

#12 José Luis Crisostomo Sánchez 2021-08-11

是否有可能在xml元素中添加@deprecated?

我知道我们将在某个时候摆脱xml文件,但我找不到一种方法来将一个废弃的标签添加到诸如颜色这样的资源中。

#13 Daniel Gómez Rico 2020-05-14

嗨,Nick,首先感谢你的介绍,其次,是否有任何禁用状态的属性?

我的意思是,有主要的和次要的,但我找不到类似primaryDisabled或secondaryDisabled的东西,或者其他每个组件都提到的禁用状态的颜色。

我应该通过直接使用颜色来设置吗?

Nick Butcher 2020-05-19

对于不同的状态,我们倾向于对主题颜色应用一个alpha。请看这些来自MDC的例子(这些例子本身可以组合成一个ColorStateList)。

https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/color/res/color

Daniel Gómez Rico 2020-05-14

或者创建一个自定义的主题属性,并在所有地方使用它?

#14 Henning Bunk 2020-04-03

了不起的文章,非常感谢。在我读这些文章之前,这对我来说是相当混乱的。

我喜欢你在 "自己动手 "一章中举的例子。但不是缺少一个行动点吗?我猜你将不得不把不同的主题应用到你的ViewGroups或Activities中。

Nick Butcher 2020-04-06

说得好,我澄清了这段文字。每个屏幕在其各自的Activity上使用不同的主题。

#15 Igor Ganapolsky 2020-03-16

`?attr/color…`和东西的问题是,Android Studio不’在编辑器的一侧显示这些颜色的预览。直接使用@color/mycolor更方便,这样我们就可以在编辑器中实时预览这些颜色。

#16 anup kunwar 2020-02-28

你能不能解释一下,使用android:background="?attr/colorPrimarySurface "如何比使用android:background="@color/myPrimarySurfaceColor "更好?

Henning Bunk 2020-04-03

请确保阅读本系列中的第一篇文章,该文章在顶部有链接。

标签