1. 准备工作
在上一个 Codelab 中,您创建了 Affirmations 应用,该应用会在 RecyclerView
中显示文本列表。
在此后续 Codelab 中,您将向应用中的每句自我肯定话语添加一张励志图片。您将使用 Material Components for Android 库中的 MaterialCardView
微件,在卡片中显示每句自我肯定话语的文本和图片。然后,您将美化界面,让用户看到的界面图文更统一且更精美,这样就完成了应用。完成后的应用屏幕截图如下:
前提条件
- 可以向应用添加图片资源。
- 可以熟练修改 XML 布局。
- 能够创建一个在
RecyclerView
中显示文本列表的应用。 - 能够为
RecyclerView
创建适配器。
学习内容
- 如何向
RecyclerView
中显示的自我肯定话语列表添加图片。 - 如何在
RecyclerView
项布局中使用MaterialCardView
。 - 如何在界面中更改视觉效果,使应用看起来更精美。
构建内容
- 一个精美的 Affirmations 应用,该应用使用
RecyclerView
显示卡片列表。每张卡片都包含一张图片和一句自我肯定话语文本。
所需条件
- 一台安装了 Android Studio 4.1 或更高版本的计算机。
- 能够连接互联网下载图片文件。
- 上一个 Codelab(即创建 Affirmations 应用)中的 Affirmations 应用(此 Codelab 中不提供起始代码;创建该应用是前提条件)。
2. 向列表项添加图片
到目前为止,您已创建适配器 ItemAdapter
以在 RecyclerView
中显示自我肯定话语字符串。这样可以很好地满足功能方面的要求,但从视觉上看,却不是很有吸引力。在此任务中,您将修改列表项布局和适配器代码以显示图片与自我肯定话语。
下载图片
- 首先,在 Android Studio 中打开上一个 Codelab 中的 Affirmations 应用项目。如果您没有该项目,请执行上一个 Codelab 中的步骤以创建该项目。然后返回此处。
- 接下来,将图片文件下载到您的计算机上。一共应该有十张图片,应用中的每句自我肯定话语各有一张图片。这些图片文件的名称应该是从
image1.jpg
到image10.jpg
。 - 在 Android Studio 中,将图片从计算机复制到项目的 res > drawable 文件夹 (
app/src/main/res/drawable
) 中。一旦将这些资源添加到应用,您便能够使用资源 ID(如R.drawable.image1
)从代码中访问这些图片(您可能必须重建代码,才能让 Android Studio 找到相应图片)。
现在,图片就可以在应用中使用了。
在 Affirmation 类中添加对图片的支持
在此步骤中,您将在 Affirmation
数据类中添加一个属性来存储图片资源 ID 的值。这样,单个 Affirmation
对象实例将包含自我肯定话语文本的资源 ID 和自我肯定话语图片的资源 ID。
- 打开
model
软件包中的Affirmation.kt
文件。 - 添加另一个名为
imageResourceId
的Int
形参,从而修改Affirmation
类的构造函数。
使用资源注解
stringResourceId
和 imageResourceId
都是整数值。虽然这看起来没有问题,但调用方可能会意外地以错误的顺序传入实参,即首先传入 imageResourceId
而不是 stringResourceId
。
为避免此问题,您可以使用资源注解。注解很有用,因为它们可以向类、方法或参数添加额外的信息。注解始终使用 @ 符号进行声明。在本例中,向字符串资源 ID 属性添加 @StringRes
注解,并向可绘制资源 ID 属性添加 @DrawableRes
注解。这样一来,如果您提供了错误类型的资源 ID,就会收到警告。
- 向
stringResourceId
添加@StringRes
注解。 - 向
imageResourceId
添加@DrawableRes
注解。 - 确保在文件的顶部且在软件包声明后面添加导入代码
androidx.annotation.DrawableRes
和androidx.annotation.StringRes
。
Affirmation.kt
package com.example.affirmations.model
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
data class Affirmation(
@StringRes val stringResourceId: Int,
@DrawableRes val imageResourceId: Int
)
初始化带图片的自我肯定话语列表
现在,您已更改 Affirmation
类的构造函数,接下来需要更新 Datasource
类。向初始化的每个 Affirmation
对象传入一个图片资源 ID。
- 打开
Datasource.kt
。您应该会看到Affirmation
的每次实例化都有一个错误。 - 对于每个
Affirmation
,将图片的资源 ID 添加为实参,如R.drawable.image1
。
Datasource.kt
package com.example.affirmations.data
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
class Datasource() {
fun loadAffirmations(): List<Affirmation> {
return listOf<Affirmation>(
Affirmation(R.string.affirmation1, R.drawable.image1),
Affirmation(R.string.affirmation2, R.drawable.image2),
Affirmation(R.string.affirmation3, R.drawable.image3),
Affirmation(R.string.affirmation4, R.drawable.image4),
Affirmation(R.string.affirmation5, R.drawable.image5),
Affirmation(R.string.affirmation6, R.drawable.image6),
Affirmation(R.string.affirmation7, R.drawable.image7),
Affirmation(R.string.affirmation8, R.drawable.image8),
Affirmation(R.string.affirmation9, R.drawable.image9),
Affirmation(R.string.affirmation10, R.drawable.image10)
)
}
}
向列表项布局添加 ImageView
如需为列表中的每句自我肯定话语显示一张图片,您需要向项布局添加 ImageView
。由于您现在有两个视图(TextView
和 ImageView
),因此需要将它们作为子视图放在 ViewGroup
中。如需在垂直列中排列视图,您可以使用 LinearLayout
。LinearLayout
会在一个方向上(垂直或水平)对齐所有子视图。
- 依次打开 res > layout > list_item.xml。围绕现有的
TextView
添加LinearLayout
,并将orientation
属性设置为vertical
。 - 将
xmlns schema
声明行从TextView
元素移至LinearLayout
元素以消除错误。
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
- 在
LinearLayout,
内的TextView,
前面,添加资源 ID 为item_image
的ImageView
。 - 将
ImageView
的宽度设置为match_parent
,并将其高度设置为194dp
。设置此值后,在任何给定时间,屏幕上应该都会显示几张卡片,卡片数量取决于屏幕大小。 - 将
scaleType
设置为centerCrop.
。 - 将
importantForAccessibility
属性设置为no
,因为图片仅用作装饰。
<ImageView
android:layout_width="match_parent"
android:layout_height="194dp"
android:id="@+id/item_image"
android:importantForAccessibility="no"
android:scaleType="centerCrop" />
更新 ItemAdapter 以设置图片
- 打开
adapter/ItemAdapter.kt
(app > java > adapter > ItemAdapter)。 - 找到
ItemViewHolder
类。 ItemViewHolder
实例应在列表项布局中存储对TextView
的引用以及对ImageView
的引用。请做以下更改。
在 textView
属性的初始化下面,添加一个名为 imageView
的 val
。使用 findViewById()
查找对 ImageView
(ID 为 item_image
)的引用,并将其赋值给 imageView
属性。
ItemAdapter.kt
class ItemViewHolder(private val view: View): RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.item_title)
val imageView: ImageView = view.findViewById(R.id.item_image)
}
- 在
ItemAdapter
中查找onBindViewHolder()
函数。 - 之前,您已将自我肯定话语的
stringResourceId
设置到ItemViewHolder
中的textView
上。现在,将自我肯定话语项的imageResourceId
设置到列表项视图的ImageView
上。
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = dataset[position]
holder.textView.text = context.resources.getString(item.stringResourceId)
holder.imageView.setImageResource(item.imageResourceId)
}
- 运行应用并滚动浏览自我肯定话语列表。
有了图片,应用看起来更漂亮了!不过,您仍然可以改进应用界面。在下一部分中,您将对应用进行细微的调整以改进界面。
3. 美化界面
到目前为止,您已经构建了一个可以正常运行的应用,该应用由自我肯定话语字符串和图片列表组成。在本部分中,您将会看到代码和 XML 中的细微更改如何使应用看起来更精美。
添加内边距
首先,在列表中的项之间添加一些空白。
- 打开
item_list.xml
(app > res > layout > item_list.xml),然后向现有的LinearLayout
添加16dp
的内边距。
list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
- 向
item_title
TextView
添加16dp
的内边距。 - 在
TextView
中,将textAppearance
属性设置为?attr/textAppearanceHeadline6
。textAppearance
是用于定义文本专用样式的属性。如需了解其他可能的预定义文本外观值,请参阅关于常见主题属性的博文中的 TextAppearances 部分。
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:textAppearance="?attr/textAppearanceHeadline6" />
- 运行应用。列表是不是看起来更美观了?
使用卡片
现在仍然很难分辨一张图片是属于它上面还是下面的自我肯定话语文本。为了解决此问题,您可以使用卡片视图。卡片视图提供了一种简单的方法来包含一组视图,同时又能为容器提供一致的样式。如需更多关于如何使用卡片的 Material Design 指导,请参阅这篇关于卡片的指南。
- 围绕现有的
LinearLayout
添加MaterialCardView
。 - 再次将架构声明从
LinearLayout
移入MaterialCardView
。 - 将
MaterialCardView
的layout_width
设置为match_parent
,并将layout_height
设置为wrap_content
。 - 添加
8dp
的layout_margin
。 - 移除
LinearLayout
中的内边距,这样就不会有太多的空白。 - 现在,再次运行应用。使用
MaterialCardView
之后,每句自我肯定话语是不是更方便区分了?
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/item_image"
android:layout_width="match_parent"
android:layout_height="194dp"
android:importantForAccessibility="no"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:textAppearance="?attr/textAppearanceHeadline6" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
更改应用主题颜色
默认应用主题颜色可能不像您自己选择的颜色一样赏心悦目。在此任务中,您会将应用主题颜色更改为蓝色。随后您可以按照自己的想法再次更改颜色!
您可以从此链接的 Material Design 调色板中找到预定义的蓝色色调。
在此 Codelab 中,您将使用 Material Design 调色板中的以下颜色:
- blue_200:
#FF90CAF9
- blue_500:
#FF2196F3
- blue_700:
#FF1976D2
添加颜色资源
在一个集中的位置(即在 colors.xml
文件中)定义应用中使用的颜色。
- 打开
colors.xml
(res > values > colors.xml)。 - 针对下面定义的蓝色向该文件中添加新的颜色资源:
<color name="blue_200">#FF90CAF9</color>
<color name="blue_500">#FF2196F3</color>
<color name="blue_700">#FF1976D2</color>
更改主题颜色
现在,您已经有了新的颜色资源,接下来可以在主题中使用它们了。
- 打开
themes.xml
(res > values > themes > themes.xml)。 - 找到
<!-- Primary brand color. -->
部分。 - 添加或更改
colorPrimary
以使用@color/blue_500
。 - 添加或更改
colorPrimaryVariant
以使用@color/blue_700
。
<item name="colorPrimary">@color/blue_500</item>
<item name="colorPrimaryVariant">@color/blue_700</item>
- 运行应用。您应该会看到应用栏颜色变成了蓝色。
更新深色主题颜色
最好为应用的深色主题选择饱和度更低的颜色。
- 打开深色主题
themes.xml
文件 (themes > themes.xml (night))。 - 添加或更改
colorPrimary
和colorPrimaryVariant
主题属性,如下所示:
<item name="colorPrimary">@color/blue_200</item>
<item name="colorPrimaryVariant">@color/blue_500</item>
- 运行应用。
- 在设备的设置中,开启深色主题。
- 应用会切换到深色主题。验证它是否看起来像下面的屏幕截图:
- 此时,您还可以在
colors.xml
文件中移除未使用的颜色(例如,在默认应用主题中使用的紫色资源)。
更改应用图标
在最后一步中,您将更新应用图标。
- 下载应用图标文件
ic_launcher_foreground.xml
和ic_launcher_background.xml
。如果您的浏览器显示了相应的文件而没有下载该文件,请依次选择文件 > 网页另存为…,以将其保存到计算机上。 - 在 Android Studio 中,删除两个文件,即
drawable/ic_launcher_background.xml
和drawable-v24/ic_launcher_foreground.xml
文件,因为这些文件用于以前的应用图标。您可以取消选中 Safe delete (with usage search) 框。 - 然后右键点击 res > drawable 文件夹,再依次选择 New > Image Asset。
- 在 Configure Image Asset 窗口中,确保选择了 Foreground layer。
- 在它下面,找到 Path 标签。
- 点击 Path 文本框内的文件夹图标。
- 找到并打开您下载到计算机上的
ic_launcher_foreground.xml
文件。
- 切换到 Background Layer 标签页。
- 点击 Path 文本框内的 Browse 图标。
- 找到并打开计算机上的
ic_launcher_background.xml
文件。不需要进行其他更改。 - 点击 Next。
- 在 Confirm Icon Path 对话框中,点击 Finish。可以覆盖现有图标。
- 作为最佳实践,您可以将新的矢量可绘制对象
ic_launcher_foreground.xml
和ic_launcher_background.xml
移入一个名为drawable-anydpi-v26
的新资源目录。自适应图标是在 API 26 中引入的,因此这些资源只会用在搭载 API 26 及更高版本(针对任何 dpi)的设备上。 - 如果
drawable-v24
目录中没有剩下任何内容,请删除该目录。 - 运行应用并注意应用抽屉中漂亮的新应用图标!
- 最后,请不要忘记为项目中的 Kotlin 和 XML 文件重新设置格式,使代码更简洁并遵循样式准则。
恭喜!您创建了一个鼓舞人心的 Affirmations 应用。
利用这些关于如何在 Android 应用中显示数据列表的知识,您接下来可以构建什么呢?
4. 解决方案代码
Affirmations 应用的解决方案代码位于下面的 GitHub 代码库中:
- 进入为此项目提供的 GitHub 代码库页面。
- 验证分支名称是否与此 Codelab 中指定的分支名称一致。例如,在以下屏幕截图中,分支名称为 main。
- 在项目的 GitHub 页面上,点击 Code 按钮,以打开一个弹出式窗口。
- 在弹出式窗口中,点击 Download ZIP 按钮,将项目保存到计算机上。等待下载完成。
- 在计算机上找到该文件(很可能在 Downloads 文件夹中)。
- 双击 ZIP 文件进行解压缩。系统将创建一个包含项目文件的新文件夹。
在 Android Studio 中打开项目
- 启动 Android Studio。
- 在 Welcome to Android Studio 窗口中,点击 Open。
注意:如果 Android Studio 已经打开,则改为依次选择 File > Open 菜单选项。
- 在文件浏览器中,前往解压缩的项目文件夹所在的位置(很可能在 Downloads 文件夹中)。
- 双击该项目文件夹。
- 等待 Android Studio 打开项目。
- 点击 Run 按钮 以构建并运行应用。请确保该应用按预期构建。
5. 总结
- 如需在
RecyclerView
中显示其他内容,请修改底层数据模型类和数据源。然后,更新列表项布局和适配器以将该数据设置到视图上。 - 使用资源注解帮助确保将正确类型的资源 ID 传入类构造函数。
- 使用 Material Components for Android 库让应用更轻松地遵循建议的 Material Design 准则。
- 使用
MaterialCardView
在 Material 卡片中显示内容。 - 在颜色和间距方面对应用进行细微的视觉调整,可使应用看起来更精美且更一致。
6. 了解更多内容
- 使用
RecyclerView
创建列表 RecyclerView
类RecyclerView
适配器RecyclerView
ViewHolder- Material Design 中的列表
- Material Design 中的卡片
MaterialCardView
- Material Components for Android 入门
- Android 样式设置:主题与样式
- 自适应图标
7. 挑战任务
在这一系列 Codelab 中,您学习了如何将 LinearLayoutManager
与 RecyclerView
搭配使用。RecyclerView
可以使用不同的 LayoutManagers 来以不同的方式设置数据的布局。
- 将
RecyclerView
的layoutManager
属性设置为GridLayoutManager
。 - 将列数更改为 3。
- 更改适配器布局以在网格中直观地查看数据。