【译】为Android设置Material Components主题

本文为 Nick Rout 发布于 Medium 的文章译文(Google 翻译)
原文链接为 Setting up a Material Components theme for Android
本文仅作为个人学习记录所用。如有涉及侵权,请相关人士尽快联系译文作者。


Android MDC 系列文章:


因此,您已经将Android应用程序迁移到AndroidX,并且在此过程中,还切换到了使用Android的Material Components而非Design Support Library。另外,也许您很幸运,需要从头开始启动应用程序并立即使用这些新库。无论哪种情况,您现在都已将包含在应用程序中的核心窗口小部件归入该com.google.android.material程序包,并附带了各种新的主题/样式属性。

本文将仅介绍新的全局主题属性和每个小部件样式属性。鉴于Theme.MaterialComponents主题扩展预先存在的Theme.AppCompat变种,它们继承了所有的属性(想colorAccentcolorControlNormal等),这将不包括在内。

让我们开始!

初始设置🏗️

这就像将单个Gradle依赖项添加到您的应用程序/模块build.gradle文件一样简单:

implementation "com.google.android.material:material: $material_version"

Android的Material Components正在积极开发中。最初的1.0.0发行版只是现有com.android.support.design类到新com.google.android.material名称空间的一部分。在此之后是独立的功能发行版,在撰写本文时,最新版本是1.2.0-alpha05。您可以在GitHub存储库上跟踪新版本。

选择“Material Components”主题🤔

与AppCompat主题一样,“材质组件”主题包含一些基本变体供您选择:

材质组件主题(从左到右):Theme.MaterialComponents,Theme.MaterialComponents.NoActionBar,Theme.MaterialComponents.Light

材质组件主题(从左到右):Theme.MaterialComponents.Light.DarkActionBar,Theme.MaterialComponents.Light.NoActionBar

每个变体的主要区别是浅色/深色调色板以及ActionBar每个主题Activity的中是否包含Window。存在DayNight这些变体以支持自动暗/亮主题。
注意1:如果您要迁移现有主题,但又不想一次获得所有新属性,请使用Theme.MaterialComponents.*.Bridge变体。
注意2:此处未显示一些辅助变体,例如Theme.MaterialComponents.Dialog.*主题。
要在您的应用中开始使用这些主题之一,请在res/styles.xml文件中添加以下内容:

<style name="AppTheme" parent="Theme.MaterialComponents.*">
    <!-- Add attributes here -->
</style>

最后,您需要在清单中引用此内容:

<manifest
    ...>
    <application
        android:theme="@style/AppTheme">
        ...
    </application>
</manifest>

注意:您也可以申请一个android:theme<activity>在你的清单。

一个简单的游乐场屏幕🎡

是的,该开始做生意了。为了说明自定义Material Components属性的效果,我们需要一个视觉辅助工具。我们将使用下面的游乐场屏幕,该屏幕使用Theme.MaterialComponents.Light基本主题,并且包含大多数“材料组件”小部件及其变体:

游乐场屏幕

Global theme attributes🌍

“The Material Components Themes”引入了可用于全局内样式化元素的新属性。这些可以分为三个主要子系统:colortypographyshape

Color

Color 属性主要包括primarysecondaryerrorsurfacebackground色,以及它们各自的辅助变体和“上”色。其中的一些已经从程序兼容性主题重复使用(例如colorPrimarycolorErrorandroid:colorBackground):

  • colorPrimary:您的应用的主要品牌颜色,主要用于主题
  • colorPrimaryVariant:您的主要品牌颜色的较浅/较暗变体,在主题中很少使用
  • colorOnPrimary:用于显示在原色上方的元素的颜色(例如,文本和图标,根据可访问性,通常为白色或半透明的黑色)
  • colorSecondary:您应用程式的次要品牌色彩,主要用于强调某些需要突出的小部件
  • colorSecondaryVariant:您的次要品牌颜色的较浅/较深变体,在主题中很少使用
  • colorOnSecondary:用于显示在辅助颜色顶部的元素的颜色
  • colorError:用于错误的颜色(通常为红色阴影)
  • colorOnError:用于显示在错误颜色顶部的元素的颜色
  • colorSurface:用于表面的颜色(即材料“纸张”)
  • colorOnSurface:用于显示在表面颜色顶部的元素的颜色
  • android:colorBackground:所有其他屏幕内容后面的颜色
  • colorOnBackground:用于显示在背景色上方的元素的颜色

可以将这些颜色添加到您的应用主题中,如下所示:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
    <item name="colorPrimary">#212121</item>
    <item name="colorPrimaryVariant">#000000</item>
    <item name="colorOnPrimary">#FFFFFF</item>
    <item name="colorSecondary">#2962FF</item>
    <item name="colorSecondaryVariant">#0039CB</item>
    <item name="colorOnSecondary">#FFFFFF</item>
    <item name="colorError">#F44336</item>
    <item name="colorOnError">#FFFFFF</item>
    <item name="colorSurface">#FFFFFF</item>
    <item name="colorOnSurface">#212121</item>
    <item name="android:colorBackground">@color/background</item>
    <item name="colorOnBackground">#212121</item>
</style>
<color name="background">#FAFAFA</color>

注意1:当前不支持十六进制颜色代码*android:colorBackground*,因此为什么要使用颜色资源。

注意2:主题系统栏的使用*android:statusBarColor**android:navigationBarColor*属性。

结果可以在我们的操场屏幕上看到:

快速预览原色/副色外观的一种好方法是使用“ 材质颜色工具”

Typography

Type 属性在文字字体重量大小大小写字母间距方面都符合Material Type System。这些属性引用实现(并以其命名)各种类型比例的样式:TextAppearance.MaterialComponents.*

  • textAppearanceHeadline1:轻,96sp
  • textAppearanceHeadline2:轻,60sp
  • textAppearanceHeadline3:常规的48sp
  • textAppearanceHeadline4:常规的34sp
  • textAppearanceHeadline5:常规,24sp
  • textAppearanceHeadline6:中20sp
  • textAppearanceSubtitle1:常规16sp
  • textAppearanceSubtitle2:中14sp
  • textAppearanceBody1:常规16sp
  • textAppearanceBody2:常规,14sp
  • <mark class="rf rg nf" style="box-sizing: inherit; cursor: pointer; background-color: rgb(255, 240, 182); color: currentcolor;">textAppearanceCaption</mark>:常规,12sp
  • textAppearanceButton:常规,14sp,全大写
  • textAppearanceOverline:常规,12sp,全大写

“材料组件”小部件将按照“材料”准则使用这些样式。

您通常希望为每种样式保留默认的粗细,大小,大小写和字母间距。但是,自定义字体确实可以使您的应用脱颖而出。一个人可能会认为这需要覆盖这些属性中的每一个。幸运的是,可以通过将以下属性添加到您的应用程序主题中,以更简洁的方式完成此操作:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
    ...
    <item name="fontFamily">@font/roboto_mono</item>
    <item name="android:fontFamily">@font/roboto_mono</item>
</style>

这些属性引用您添加到文件夹中的XML字体或可下载字体res/font并将自定义字体应用于应用程序中的每个小部件和文本样式。肯定有一段时间,在Android上并非如此轻松!

但是,如果您希望自定义“材料组件”文本外观样式中的一种,则可以这样进行:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
    ...
    <item name="textAppearanceButton">@style/AppTextAppearance.Button</item>
</style>
<style name="AppTextAppearance.Button" parent="TextAppearance.MaterialComponents.Button">
    ...
    <item name="android:textAllCaps">false</item>
</style>

结果可以在我们的操场屏幕上观察到:

具有自定义全局类型属性的游乐场屏幕

最后,如果您正在寻找免费使用的自定义字体(也可以与“可下载的字体”很好地兼容),则Google字体是一个不错的起点。

Shape

Shape 属性是指应用程序中每个表面和小部件的一般形式。当您认为这些组件的宽度/高度可以变化并且可以升高/升高/轮廓化时,这可以减少到定制的一个方面……角落。

材料零件的角落可以是部分(默认)或切断 cornerFamily,并有一个cornerSize自定义大小。可以将处理应用于所有角落或子集。形状主题属性参考ShapeAppearance.MaterialComponents.*样式:

  • shapeAppearanceSmallComponent:用于小零件,例如按钮和芯片
  • shapeAppearanceMediumComponent:适用于中等组件,例如卡
  • shapeAppearanceLargeComponent:适用于大型组件,例如底板

“材料组件”小部件将按照“材料”准则使用这些样式。

如果您希望自定义“Material Components”形状外观样式,则可以这样进行:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
    ...
    <item name="shapeAppearanceSmallComponent">@style/AppShapeAppearance.SmallComponent</item>
    <item name="shapeAppearanceMediumComponent">@style/AppShapeAppearance.MediumComponent</item>
</style>
<style name="AppShapeAppearance.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent">
    <item name="cornerFamily">cut</item>
    <item name="cornerSize">8dp</item>
</style>
<style name="AppShapeAppearance.MediumComponent" parent="ShapeAppearance.MaterialComponents.MediumComponent">
    <item name="cornerFamily">cut</item>
    <item name="cornerSize">8dp</item>
</style>

结果可以在我们的操场屏幕上看到:

具有全局形状属性的游乐场屏幕已定制

Widget styles and attributes 📱

尽管全局主题满足了我们的大部分需求,但有时我们还是希望自定义各个小部件的属性。我们将探讨通用小部件的样式(和相关属性),以及如何在您的“材料组件”主题中引用这些样式。

Buttons

Material Buttons 包括四个主要变体,这些变体均从基本Widget.MaterialComponents.Button样式继承,每个变体都带有可选的样式后缀:凸起(默认,无后缀),未升高*.UnelevatedButton),轮廓*.OutlinedButton)和文本*.TextButton)。所有按钮变体均使用textAppearanceButton主题属性作为其印刷样式。

自定义这些样式的关键属性如下:

  • backgroundTint:色调颜色应用于按钮背景。对于文本按钮和colorPrimary所有其他变体,默认启用的颜色是透明的。
  • iconTint:色调颜色应用于可选的按钮图标。默认启用的颜色是colorPrimary用于文本按钮和colorOnPrimary所有其他变体的颜色。
  • rippleColor:按钮触摸波纹的颜色。默认颜色是colorOnPrimary凸起/未凸起按钮和colorPrimary轮廓/文本按钮的颜色。
  • strokeColor:按钮背景周围的笔触颜色。默认颜色是colorOnSurface轮廓按钮的颜色,其他颜色是透明的。
  • strokeWidth:按钮背景周围的笔触宽度。概述按钮的默认值为1dp,其他所有变量的默认值为0dp。
  • shapeAppearance:按钮背景的形状外观。默认值为shapeAppearanceSmallComponent

基本按钮样式(由MaterialButtonwidget类使用)可以自定义并全局应用,如下所示:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
    ...
    <item name="materialButtonStyle">@style/AppButton</item>
</style>
<style name="AppButton" parent="Widget.MaterialComponents.Button">
    <item name="backgroundTint">?attr/colorSecondary</item>
</style>

结果可以在我们的操场屏幕上看到:

自定义按钮小部件样式

Text Fields

Material Text Fields 包括两个主要变体。由于移植了预先存在的AppCompat TextInputLayoutTextInputEditText类,因此实际上有两种基本样式:Widget.MaterialComponents.TextInputLayout.*Widget.MaterialComponents.TextInputEditText.*。这些变体具有样式后缀,并包括实心框(默认*.FilledBox)和轮廓框*.OutlinedBox)。所有文本字段变体均使用标准的文本外观作为输入,并将textAppearanceCaption主题属性用作“辅助”文本(标签,错误,计数器等)。

定制Widget.MaterialComponents.TextInputLayout.*样式的关键属性如下:

  • boxBackgroundMode:框背景,其可以是所述的模式filledoutlinenone
  • boxBackgroundColor:文本字段背景的颜色。默认启用的颜色colorOnSurface用于填充框文本字段,透明用于轮廓框文本字段。
  • boxStrokeColor:文本字段背景周围的笔触颜色。colorOnSurface轮廓框文本字段的默认颜色为(默认状态),填充框文本字段的默认颜色为忽略。
  • hintTextColor/ errorTextColor/ counterTextColor:各种颜色不同的“帮手”文本子组件。
  • shapeAppearance:文本字段背景的形状外观。默认值为shapeAppearanceSmallComponent

基本文本字段样式(由TextInputLayout小部件类使用)可以像下面这样自定义和全局应用:

< style name =“ AppTheme” parent =“ Theme.MaterialComponents.Light” > 
    ... 
    < item name =“ textInputStyle” > @ style / AppTextField </ item > 
</ style > 
< style name =“ AppTextField” parent =“ Widget.MaterialComponents.TextInputLayout.FilledBox“>
     < item name =” boxBackgroundColor“ > @ color / text_field_background </ item > 
< / style >

注意:*text_field_background*是一个使用默认值相同的alpha值的*res/color*``*<selector>*``*colorSecondary**boxBackgroundColor*``*<selector>*

结果可以在我们的操场屏幕上看到:

自定义文本字段小部件样式

Cards

Material Cards 被认为是“表面”,并使用了Widget.MaterialComponents.CardView样式。用于自定义它们的关键属性如下:

  • cardBackgroundColor:卡片背景的颜色。默认颜色是colorSurface
  • cardElevation:卡的高度。默认值为1dp。
  • shapeAppearance:卡片背景的形状外观。默认值为shapeAppearanceMediumComponent

基本卡样式(由MaterialCardView小部件类使用)可以自定义并全局应用,如下所示:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
    ...
    <item name="materialCardViewStyle">@style/AppCard</item>
</style>
<style name="AppCard" parent="Widget.MaterialComponents.CardView">
    <item name="cardElevation">8dp</item>
</style>

结果可以在我们的操场屏幕上看到:

自定义卡片小部件样式

Bottom Navigation

“Material Bottom Navigation”包括两个从基本Widget.MaterialComponents.BottomNavigationView样式继承的主要变体,带有一个可选的样式后缀:表面(默认,无后缀)和彩色*.Colored)。底部导航标签将textAppearanceCaption主题属性用于其排版样式。

自定义这些样式的关键属性如下:

  • backgroundTint:底部导航背景的颜色。默认颜色colorSurface用于表面底部导航和colorPrimary彩色底部导航。
  • itemTextColor/ itemIconTint:底部导航项目图标和标签的颜色。对于表面底部导航和彩色底部导航,默认颜色为colorOnSurface/ colorPrimary(选定)colorOnPrimary
  • itemHorizontalTranslationEnabled:用于设置在选择底部导航项时是否应显示翻译动画的标志。默认值为false。

基本的底部导航样式(由BottomNavigationViewwidget类使用)可以像下面这样自定义和全局应用:

< style name =“ AppTheme” parent =“ Theme.MaterialComponents.Light” > 
    ... 
    < item name =“ bottomNavigationStyle” > @ style / AppBottomNavigation </ item > 
</ style > 
< style name =“ AppBottomNavigation” parent =“ Widget.MaterialComponents.BottomNavigation.Colored“ />

结果可以在我们的操场屏幕上看到:

自定义的底部导航小部件样式

这当然不是详尽无遗的。有关所有组件及其属性的更全面列表,请参见Android Docs材料组件

Build a Material Theme

适用于Android的Material Components库包含一个模块,可让您轻松自定义现有的Material Theme。它为您提供了一套XML文件(color.xml/ night/color.xmltype.xmlshape.xml),它包括所有必要的基准主题的属性这篇文章中提到。可以在相应的示例应用程序中调整和预览这些值。当您对所选的值满意时,可以将文件拖放到新的/现有的Android Studio项目中。在Glitch上也可以使用网络版本。

The “Build a Material Theme” sample app

更多资源📚


希望本文能为您使用Android的Material Components提供一些深入了解您的应用的主题。如果您有任何疑问,想法或建议,那么我很乐意收到您的来信!

在Twitter上找到我@ricknout

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容

  • 1.落笔缘由 本文主要是对Android主题和样式的研究,本文主要是以摘抄官方文档(地址在参考文章中给出)的内容,...
    lgy_gg阅读 3,929评论 0 1
  • 样式和主题(Styles and Themes) 一个样式(Style)是一个包含了指定样子和格式的作用于视图控件...
    张云飞Vir阅读 2,823评论 0 51
  • Theming your Angular Material app 将您的Angular Material应用程序...
    王义杰阅读 2,345评论 0 0
  • 1.1 问题 你要让自己的应用程序在所有用户可能运行的Android版本上创建一致的外观和体验,同时减少维护这些自...
    Jennyni1122阅读 705评论 0 1
  • 我生来便不会与人聊天。 不知道该如何开始一个话题,更不知道该如何继续一个话题。 我总觉得我说出的话语有些不合时宜,...
    日目阅读 216评论 2 1