Kotlin Android 基础知识 10.1:样式和主题

此 Codelab 是“Android Kotlin 基础知识”课程的一部分。如果您按顺序学习这些 Codelab,您将会充分发掘此课程的价值。“Android Kotlin 基础知识”Codelab 着陆页列出了所有课程 Codelab。

设计简介

此系列 Codelab 侧重于 Android 开发中最重要的方面之一:应用设计。应用设计中显而易见的方面包括视图、文字和按钮,以及它们在屏幕上的位置,还有它们使用的颜色和字体。向用户提示接下来该怎么做也是设计的重要方面。用户需要能够一目了然地了解自己正在查看的内容、哪些内容比较重要以及可以执行哪些操作。

比较以下两个界面。请注意,通过移动元素并突出显示重要内容,您可以帮助用户了解发生了什么。对于简单的界面,良好的设计通常意味着显示更少的内容。对于包含大量重要信息的界面,出色的设计可让用户一目了然地了解密集的信息。在开发 Android 应用时,您可能会听到信息架构 (IA) 这个概念。

另一个设计层面是构建连贯的用户流或用例,以便用户完成任务。这种设计称为用户体验设计 (UXD),有些设计师专门从事这方面的工作。

如果您无法联系设计师,可以参考以下提示来开始设计:

  • 定义用例。写下用户应如何通过您的应用完成任务。
  • 实现设计。不要对初稿过于执着,只要“足够好”即可,因为在了解真实用户与初稿的互动情况后,您会对其进行更改。
  • 获取反馈。找到任何可以劝说其测试您的应用的人,例如您的家人、朋友,甚至是您刚在 Google 开发者群组中认识的人。让他们使用您的应用来执行某个使用情形,而您则在一旁观看并做详细记录。
  • 优化!根据所有这些信息改进应用,然后再次进行测试。

在设计出色的应用体验时,您还可以思考以下问题。在前面的 Codelab 中,您学习了解决这些问题的技巧:

  • 当用户旋转设备时,应用是否会丢失其状态?
  • 用户打开应用后会发生什么情况?用户看到的是加载微调框,还是离线缓存中的数据已准备就绪?
  • 应用是否以高效的方式编码,并确保应用始终能响应用户触摸操作?
  • 应用与后端系统的互动是否永远不会导致向用户呈现奇怪、不正确或过时的数据?

在为更广泛的受众群体开发应用时,务必要让应用尽可能面向更多类型的用户。例如:

  • 许多用户会以不同的方式与计算机系统互动。许多用户是色盲,对于某个用户来说对比鲜明的颜色可能不适合另一个用户。许多用户都有视力障碍,从需要老花镜到完全失明不等。
  • 有些用户无法使用触摸屏,而是通过其他输入设备(例如按钮)进行互动。

出色的设计是吸引用户使用您的应用的最重要方式。

这些 Codelab 篇幅有限,无法教您有关 Android 设计的所有知识,但它们能让您朝着正确的方向入门,您可以继续自行学习和开发。

您应当已掌握的内容

您应熟悉以下内容:

  • 如何创建包含 activity 和 fragment 的应用,以及如何在 fragment 之间导航并传递数据
  • 使用视图和视图组来布局界面 (UI),包括 RecyclerView
  • 如何使用架构组件(包括 ViewModel)和推荐的架构来创建结构合理且高效的应用
  • 数据绑定、协程以及如何处理点击
  • 如何使用 Room 数据库连接到互联网并在本地缓存数据
  • 如何设置视图属性
  • 如何将资源提取到 XML 资源文件中以及如何使用 XML 资源文件中的资源

学习内容

  • Android 样式系统的基础知识
  • 如何使用属性、样式和主题自定义应用

您将执行的操作

  • 使用视图属性、样式和主题改进入门应用的设计

GDG-finder 初始应用基于您在本课程中目前为止所学的所有知识构建而成。

该应用使用 ConstraintLayout 来布局三个界面。其中两个屏幕只是布局文件,您将使用它们来探索 Android 上的颜色和文本。

第三个界面是 GDG 查找器。GDG(Google 开发者社区)是由开发者组成的社区,专注于 Google 技术,包括 Android。世界各地的 GDG 都会举办聚会、会议、学习聚会和其他活动。

在开发此应用时,您需要处理真实的 GDG 列表。查找器界面会使用设备的位置信息按距离对 GDG 进行排序。

如果您很幸运,您所在的地区有 GDG,您可以访问其网站并报名参加其活动!GDG 活动是结识其他 Android 开发者并学习本课程未涵盖的行业最佳实践的好方法。

以下屏幕截图展示了您的应用在此 Codelab 的开始和结束时会发生哪些变化。

Android 提供了一个丰富的样式系统,可让您控制应用中所有视图的外观。您可以使用主题、样式和视图属性来影响样式。下图总结了每种样式设置方法的优先级。金字塔图显示了系统应用样式方法的顺序(从底部到顶部)。例如,如果您在主题背景中设置了文字大小,然后在视图属性中将文字大小设置为其他值,则视图属性会覆盖主题背景样式。

视图属性

  • 使用视图属性可为每个视图明确设置属性。(与样式不同,视图属性不可重复使用。)
  • 您可以使用可通过样式或主题背景设置的每个属性。

用于自定义或一次性设计,例如边距、内边距或限制条件。

样式

  • 使用样式可创建一组可重复使用的样式信息,例如字号或颜色。
  • 适合用于声明在整个应用中使用的一小部分常见设计。

将样式应用于多个视图,并替换默认样式。例如,使用样式来创建样式一致的标题或一组按钮。

默认样式

  • 这是 Android 系统提供的默认样式。

主题

  • 使用主题为整个应用定义颜色。
  • 使用主题为整个应用设置默认字体。
  • 适用于所有视图,例如文本视图或单选按钮。
  • 用于配置可始终应用于整个应用的属性。

TextAppearance

  • 仅使用文本属性(例如 fontFamily)设置样式。

当 Android 为视图设置样式时,它会应用主题、样式和属性的组合,您可以自定义这些内容。属性始终会覆盖样式或主题中指定的任何内容。样式始终会覆盖主题背景中指定的任何内容。

以下屏幕截图显示了 GDG-finder 应用在浅色主题(左)和深色主题(右)下的外观,以及在采用自定义字体和标题大小时的外观。此功能可以通过多种方式实现,您将在本 Codelab 中学习其中的一些方式。

在此任务中,您将使用属性来设置应用布局中文字的标题样式。

  1. 下载并运行 GDG-finder 起始应用
  2. 请注意,首页上有很多格式统一的文字,这使得用户很难了解网页的内容和重要信息。
  3. 打开 home_fragment.xml 布局文件。
  4. 请注意,该布局使用 ConstraintLayout 来定位 ScrollView 内的元素。
  5. 请注意,对于每个视图,约束和边距布局属性都是在视图中设置的,因为这些属性往往会针对每个视图和屏幕进行自定义。
  6. title 文本视图中,添加 textSize 属性,将文字大小更改为 24sp

    提醒一下,sp 表示缩放无关像素,它会根据像素密度和用户在设备设置中设置的字体大小偏好设置进行缩放。Android 会在绘制文字时确定文字在屏幕上应显示的大小。请始终使用 sp 来表示文字大小。
<TextView
       android:id="@+id/title"
...

android:textSize="24sp"
  1. title 文本视图的 textColor 设置为不透明的灰色,方法是将它设置为 aRGB 值 #FF555555
<TextView
       android:id="@+id/title"
...

android:textColor="#FF555555"
  1. 如需在 Android Studio 中打开预览标签页,请依次选择 View > Tool Windows > Preview,或点击布局编辑器右边缘的垂直预览按钮。在预览中,验证标题是否为灰色且比之前更大,如下所示。

  1. 将字幕的样式设置为与标题相同的颜色,但字体较小,即 18sp。(默认 Alpha 为 FF,即不透明。如果您不更改 alpha 值,可以省略该值。)
<TextView
       android:id="@+id/subtitle"
...
android:textSize="18sp"
android:textColor="#555555"

  1. 在此 Codelab 中,我们的目标是让应用在看起来专业的同时又带有一丝奇幻色彩,但您可以根据自己的喜好设置样式。为 subtitle 文本视图尝试以下属性。使用预览标签页查看应用外观的变化。然后移除这些属性。
<TextView
       android:id="@+id/subtitle"
       ...
       android:textAllCaps="true"
       android:textStyle="bold"
       android:background="#ff9999"
  1. 在继续之前,请务必撤消 subtitle 视图中的 textAllCapstextStylebackground 属性。
  2. 运行应用,此时应用看起来应该已经更美观了。

在应用中使用字体时,您可以将必需的字体文件作为 APK 的一部分进行交付。虽然此解决方案很简单,但通常不建议使用,因为这会使您的应用需要更长时间才能下载和安装。

Android 允许应用在运行时使用可下载字体 API 下载字体。如果您的应用使用的字体与设备上其他应用使用的字体相同,Android 只会下载一次该字体,从而节省设备的存储空间。

在此任务中,您将使用可下载的字体来设置应用中每个使用相应主题的视图的字体。

第 1 步:应用可下载的字体

  1. Design 标签页中打开 home_fragment.xml
  2. Component Tree 窗格中,选择 title 文本视图。
  3. 属性窗格中,找到 fontFamily 属性。您可以在所有属性部分中找到它,也可以直接搜索它。
  4. 点击下拉箭头。
  5. 滚动到更多字体 ,然后选择该选项。系统会打开一个资源窗口。

  1. 资源窗口中,搜索 lobsterlo
  2. 在结果中,选择 Lobster Two
  3. 在右侧字体名称下方,选择 创建可下载字体单选按钮。点击确定
  4. 打开 Android 清单文件。
  5. 在清单底部附近,找到新的 <meta-data> 标记,该标记的 nameresource 属性设置为 "preloaded_fonts"。此标记会告知 Google Play 服务,相应应用想要使用下载的字体。当您的应用运行并请求 Lobster Two 字体时,如果设备上尚无该字体,字体提供程序会从互联网下载该字体。
<meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts"/>
  1. res/values 文件夹中,找到 preloaded_fonts.xml 文件,该文件定义了列出相应应用的所有可下载字体的数组。
  2. 同样,res/fonts/lobster_two.xml 文件包含有关字体的信息。
  3. 打开 home_fragment.xml,并在代码和预览中注意,Lobster Two 字体已应用于 title TextView,因此也应用于标题。

  1. 打开 res/values/styles.xml 并检查为项目创建的默认 AppTheme 主题。目前,它如下所示。如需将新的 Lobster Two 字体应用于所有文本,您需要更新此主题。
  2. <style> 标记中,注意 parent 属性。每个样式标记都可以指定父级并继承父级的所有属性。该代码指定了 Android 库定义的 ThemeMaterialComponents 主题,用于指定从按钮的工作方式到工具栏的绘制方式的所有内容。该主题具有合理的默认设置,因此您可以仅自定义所需的部分。如上方的屏幕截图所示,该应用使用的是不含操作栏 (NoActionBar) 的 Light 版本的主题。
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.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>
  1. AppTheme 样式中,将字体系列设置为 lobster_two。您需要同时设置 android:fontFamilyfontFamily,因为父主题同时使用了这两个属性。您可以在设计标签页中勾选 home_fragment.xml,以预览更改。
<style name="AppTheme"  
...    
        <item name="android:fontFamily">@font/lobster_two</item>
        <item name="fontFamily">@font/lobster_two</item>
  1. 再次运行应用。新字体已应用于所有文本!打开抽屉式导航栏并移动到其他屏幕,您会看到字体也已应用到这些屏幕。

第 2 步:将主题应用于标题

  1. home_fragment.xml 中,找到具有 lobster_two 字体属性的 title 文本视图。删除 fontFamily 属性并运行应用。由于主题设置了相同的字体系列,因此没有任何变化。
  2. 将另一个 fontFamily 属性放回 title 文本视图中:
    app:fontFamily="serif-monospace"
    确保它位于 app 空间中!
<TextView
       android:id="@+id/title"
       ...
       app:fontFamily="serif-monospace"
  1. 运行应用,您会看到视图的本地属性会替换主题。
  1. title 文本视图中移除了 fontFamily 属性。

主题非常适合为应用应用常规主题,例如默认字体和主色。属性非常适合用于设置特定视图的样式,以及添加边距、内边距和限制条件等布局信息,这些信息往往因屏幕而异。

在样式层次结构金字塔的中间是样式。样式是可重复使用的属性“组”,您可以将其应用于所选的视图。在此任务中,您将为标题和副标题使用样式。

第 1 步:创建样式

  1. 打开 res/values/styles.xml
  2. <resources> 标记内,使用 <style> 标记定义新样式,如下所示。
<style name="TextAppearance.Title" parent="TextAppearance.MaterialComponents.Headline6">
</style>

在命名样式时,请务必将样式名称视为语义。根据样式的用途(而非样式影响的属性)选择样式名称。例如,将此样式命名为 Title,而不是 LargeFontInGrey。此样式将用于应用中任何位置的任何标题。按照惯例,TextAppearance 样式称为 TextAppearance.Name,因此在本例中,名称为 TextAppearance.Title

样式可以有父级,就像主题可以有父级一样。但这次,样式扩展的是样式 TextAppearance.MaterialComponents.Headline6,而不是主题。此样式是 MaterialComponents 主题的默认文本样式,因此通过扩展此样式,您可以修改默认样式,而不是从头开始。

  1. 在新样式中,定义两个项。在一个商品中,将 textSize 设置为 24sp。在另一个商品中,将 textColor 设置为之前使用的同一深灰色。
 <item name="android:textSize">24sp</item>
 <item name="android:textColor">#555555</item>
  1. 为字幕定义另一种样式。将该文件命名为 TextAppearance.Subtitle
  2. 由于此样式与 TextAppearance.Title 的唯一区别在于文字大小,因此请将此样式设为 TextAppearance.Title 的子样式。
  3. Subtitle 样式中,将文字大小设置为 18sp。下面是完成后的样式:
<style name="TextAppearance.Subtitle" parent="TextAppearance.Title" >
   <item name="android:textSize">18sp</item>
</style>

第 2 步:应用您创建的样式

  1. home_fragment.xml 中,添加 TextAppearanceTitle 样式添加到 title 文本视图。删除 textSizetextColor 属性。

    主题会替换您设置的所有 TextAppearance 样式。(Codelab 开头的金字塔图显示了样式应用的顺序。)使用 textAppearance 属性将样式作为 TextAppearance 应用,以便 Theme 中设置的字体替换您在此处设置的字体。
<TextView
       android:id="@+id/title"
       android:textAppearance="@style/TextAppearance.Title"
  1. 此外,还要向 subtitle 文本视图添加 TextAppearance.Subtitle 样式,并删除 textSizetextColor 属性。您还必须将此样式作为 textAppearance 应用,以便主题中设置的字体替换您在此处设置的字体。
<TextView
       android:id="@+id/subtitle"
       android:textAppearance="@style/TextAppearance.Subtitle"
  1. 运行应用,现在您的文本已采用一致的样式。

Android Studio 项目:GDGFinderStyles

  • 在视图中使用主题、样式和属性来更改视图的外观。
  • 主题会影响整个应用的样式,并提供许多预设的颜色、字体和字号值。
  • 属性适用于设置该属性的视图。如果您有仅适用于一个视图的样式(例如内边距、外边距和约束条件),请使用属性。
  • 样式是可供多个视图使用的一组属性。例如,您可以为所有内容标题、按钮或文本视图设置样式。
  • 主题和样式会继承其父主题或父样式的属性。您可以创建样式层次结构。
  • 属性值(在视图中设置)会替换样式。样式会替换默认样式。样式会覆盖主题背景。主题会替换通过 textAppearance 属性设置的任何样式。

  • 使用 <style><item> 标记在 styles.xml 资源文件中定义样式。
<style name="TextAppearance.Subtitle" parent="TextAppearance.Title" >
   <item name="android:textSize">18sp</item>
</style>

使用可下载字体可让用户使用字体,而不会增加 APK 的大小。如需为视图添加可下载字体,请执行以下操作:

  1. 设计标签页中选择视图,然后从 fontFamily 属性的下拉菜单中选择更多字体
  2. 资源对话框中,找到一种字体,然后选择创建可下载的字体单选按钮。
  3. 验证 Android 清单是否包含预加载字体的元数据标记。

当应用首次请求字体时,如果该字体尚不可用,字体提供程序会从互联网下载该字体。

Android 开发者文档:

其他资源:

此部分列出了在由讲师主导的课程中,学生学习此 Codelab 后可能需要完成的家庭作业。讲师自行决定是否执行以下操作:

  • 根据需要布置作业。
  • 告知学生如何提交家庭作业。
  • 给家庭作业评分。

讲师可以酌情采纳这些建议,并且可以自由布置自己认为合适的任何其他家庭作业。

如果您是在自学此 Codelab,可随时通过这些家庭作业来检测您的知识掌握情况。

回答以下问题

问题 1

哪个标记用于定义主题?

<style>

<theme>

<meta-tag>

<styling>

问题 2

以下哪一项不适合使用样式?

▢ 指定视图的约束条件。

▢ 指定标题的背景颜色。

▢ 统一各个视图的字体大小。

▢ 指定一组视图的文字颜色。

问题 3

主题和样式有什么区别?

▢ 主题会应用到整个应用,而样式可以应用到特定视图。

▢ 主题无法从其他主题沿用,但样式可以从其他样式沿用。

▢ 样式不能从其他样式沿用,但主题可以从其他主题沿用。

▢ 主题由 Android 系统提供,而样式则由开发者定义。

问题 4

如果应用中的 TextView 具有将字号设置为 12spTheme、将字号设置为 14sp 的已定义样式以及值为 16spfontSize 属性,那么屏幕上显示的字号是多少?

12sp

14sp

16sp

18sp

开始学习下一课:10.2:Material Design、尺寸和颜色

如需本课程中其他 Codelab 的链接,请参阅“Android Kotlin 基础知识”Codelab 着陆页