此 Codelab 是“Android Kotlin 基础知识”课程的一部分。如果您按顺序学习这些 Codelab,您将会充分发掘此课程的价值。“Android Kotlin 基础知识”Codelab 着陆页列出了所有课程 Codelab。
简介
RecyclerView
的主要优势之一是,它可让您使用布局管理器来控制和修改布局策略。LayoutManager
用于管理 RecyclerView
中内容的排列方式。
RecyclerView
针对常见用例提供开箱即用的布局管理器。例如,对于水平列表和垂直列表您可以使用 LinearLayout
,对于网格您可以使用 GridLayout
。对于更复杂的用例,您需要实现自定义 LayoutManager
。
在此 Codelab 中,您将在上一个 Codelab 的睡眠跟踪器应用的基础上进行构建,学习如何使用网格布局(而非列表)显示数据。(如果您没有上一个 Codelab 的应用,可以下载此 Codelab 的起始代码。)
您应当已掌握的内容
您应熟悉以下内容/操作:
- 使用
Activity
、Fragments
和Views
构建基本界面 - 在 fragment 之间导航,并使用
safeArgs
在 fragment 之间传递数据 - 视图模型、视图模型工厂和转换
LiveData
及其观察者- 如何创建
Room
数据库,创建 DAO 和定义实体 - 如何将协程用于数据库任务和其他长时间运行的任务
- 如何使用
Adapter
、ViewHolder
和项布局实现基本RecyclerView
- 如何为
RecyclerView
实现数据绑定 - 如何创建和使用绑定适配器来转换数据
学习内容
- 如何使用不同的
LayoutManager
更改数据在RecyclerView
中的显示方式 - 如何为您的睡眠数据创建网格布局
实践内容
- 在本系列上一个 Codelab 的睡眠跟踪器应用的基础上进行构建。
- 将应用中的
RecyclerView
显示的睡眠数据列表替换为睡眠数据网格。
睡眠跟踪器应用有两个屏幕(由 fragment 表示),如下图所示。
左侧所示的第一个屏幕包含用于开始和停止跟踪的按钮。这个屏幕会显示用户的一些睡眠数据。CLEAR 按钮用于永久删除应用针对用户收集的所有数据。右侧所示的第二个屏幕用于选择睡眠质量评分。
此应用使用简化的架构,其中包含界面控制器、视图模型和 LiveData
,以及 Room
数据库以持久存储睡眠数据。
睡眠数据显示在 RecyclerView
中。在此 Codelab 中,您需要更改应用以使用 GridLayout
。最终屏幕将如以下屏幕截图所示。
在上一个 Codelab 中,当您将 RecyclerView
添加到 fragment_sleep_tracker.xml
时,您添加了一个没有任何自定义设置的 LinearLayoutManager
。此代码以垂直列表的形式显示数据。
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
LinearLayoutManager
是 RecyclerView
最常用而且最直观的布局管理器,它支持水平和垂直放置子视图。例如,您可以使用 LinearLayoutManager
创建一个图片轮播界面,供用户横向滚动各个图片。
GridLayout
另一个常见用例是需要向用户显示大量数据,您可以使用 GridLayout
执行此操作。RecyclerView
的 GridLayoutManager
将数据布局为可滚动的网格,如下所示。
从设计角度来看,GridLayout
最适合可以用图标或图片表示的列表,例如照片浏览应用中的列表。在睡眠跟踪器应用中,您可以用大图标网格的形式显示每晚的睡眠数据。这种设计让用户可以一目了然地了解自己的睡眠质量。
GridLayout 如何布局列表项
GridLayout
将各列表项分成网格的各个行和列。假定您采用的是垂直滚动方式,默认情况下,一行中的每个列表项会占据一个“span”。(在这种情况下,一个 span 相当于一列的宽度。)
在下面的前两个示例中,每一行由三个 span 组成。默认情况下,GridLayoutManager
会在一个 span 中布局每个列表项,直到达到您指定的 span 计数为止。达到 span 计数时,它会换行至下一行。
默认情况下,每一项占用一个 span,但您可以通过指定占用的 span 数来扩大项的宽度。例如,最右侧屏幕的顶部项(如下所示)会占用三个 span。
在此任务中,您将获取在上一个练习中完成的 RecyclerView
,并更新它以使用 GridLayoutManager
显示数据。您可以继续使用上一个 Codelab 中的睡眠跟踪器应用,也可以从 GitHub 下载 RecyclerViewGridLayout-Starter 应用。
第 1 步:更改 LayoutManager
- 如果需要,请从 GitHub 下载此 Codelab 的 RecyclerViewGridLayout-Starter 应用,并在 Android Studio 中打开项目。
- 打开
fragment_sleep_tracker.xml
布局文件。 - 从
sleep_list
RecyclerView
定义中移除布局管理器。
要删除的代码:
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager
- 打开
SleepTrackerFragment.kt
。 - 在
OnCreateView()
中的return
语句前面,创建包含 3 个 Span 的新垂直方向(从上到下)。GridLayoutManager
构造函数最多接受四个参数:上下文,即activity
;数字跨度(默认垂直布局中的列);方向(默认为垂直);方向是否为反向布局(默认为false
)。
val manager = GridLayoutManager(activity, 3)
- 在该行的下方,告知
RecyclerView
使用此GridLayoutManager
。RecyclerView
位于绑定对象中,并被命名为sleepList
。(请参见fragment_sleep_tracker.xml
。)
binding.sleepList.layoutManager = manager
第 2 步:更改布局
list_item_sleep_night.xml
中的当前布局每晚使用一整行显示数据。在此步骤中,您将为网格定义一个更紧凑的方形项目布局。
- 打开
list_item_sleep_night.xml
。 - 删除
sleep_length
TextView
,因为新设计不需要它。 - 移动
quality_string
TextView
,使其显示在ImageView
下方。为此,您必须更新几项内容。下面是quality_string
TextView
的最终布局:
<TextView
android:id="@+id/quality_string"
android:layout_width="0dp"
android:layout_height="20dp"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/quality_image"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/quality_image"
app:layout_constraintTop_toBottomOf="@+id/quality_image"
tools:text="Excellent!!!"
app:sleepQualityString="@{sleep}" />
- 在 Design 视图中,验证
quality_string
TextView
是否位于ImageView
下方。
因为您使用的是数据绑定,所以不需要更改 Adapter
中的任何内容。代码应该就能正常运行,并且您的列表应以网格形式显示。
- 运行应用并观察睡眠数据在网格中的显示方式。
请注意,ConstraintLayout
仍会采用整个宽度。GridLayoutManager
会根据视图的跨距为其提供固定宽度。GridLayoutManager
在布局网格、添加空格或裁剪内容时,会尽力满足所有约束条件。
- 在
SleepTrackerFragment
中,在用于创建GridLayoutManager
的代码中,将GridLayoutManger
的 span 数量更改为 1。运行应用,您会看到一个列表。
val manager = GridLayoutManager(activity, 1)
- 将
GridLayoutManager
的 Span 数量更改为 10 并运行应用。请注意,GridLayoutManager
适合连续放置 10 个项目,但这些项目现在会被裁剪。 - 将跨度计数更改为 5,将方向更改为
GridLayoutManager.VERTICAL
。运行应用并注意水平滚动状况如何。您需要一个不同的布局来改善外观。
val manager = GridLayoutManager(activity, 5, GridLayoutManager.HORIZONTAL, false)
- 别忘了将跨距计数设置回 3 并将方向重置为垂直!
Android Studio 项目:RecyclerViewGridLayout
- 布局管理器用于管理
RecyclerView
中内容的排列方式。 RecyclerView
具有适用于常见用例的开箱即用布局管理器,例如用于水平和垂直列表的LinearLayout
,以及用于网格的GridLayout
。- 对于更复杂的用例,请实现自定义
LayoutManager
。 - 从设计角度来看,
GridLayout
最适用于可以用图标或图片表示的项的列表。 GridLayout
将各列表项分成网格的各个行和列。假设垂直滚动,一行中的每个列表项都会占用所谓的“跨度”。- 您可以自定义某个项的 span 数,从而创建更有趣的网格,而无需自定义布局管理器。
- 为网格中的一项创建项布局,布局管理器负责排列这些项。
- 您可以在包含
<RecyclerView>
元素的 XML 布局文件中为RecyclerView
设置LayoutManager
,或以编程方式设置。
Udacity 课程:
Android 开发者文档:
此部分列出了在由讲师主导的课程中,学生学习此 Codelab 后可能需要完成的家庭作业。讲师自行决定是否执行以下操作:
- 根据需要布置作业。
- 告知学生如何提交家庭作业。
- 给家庭作业评分。
讲师可以酌情采纳这些建议,并且可以自由布置自己认为合适的任何其他家庭作业。
如果您是在自学此 Codelab,可随时通过这些家庭作业来检测您的知识掌握情况。
回答以下问题
问题 1
以下哪些是 Android 提供的布局管理器?请选择所有适用的选项。
▢ LinearLayouManager
▢ GridLayoutManager
▢ CircularLayoutManager
StaggeredGridLayoutManager
号
问题 2
什么是“跨度”?
▢ GridLayoutManager
创建的网格大小。
▢ 网格中列宽。
▢ 网格中项目的尺寸。
▢ 垂直方向网格中的列数。
开始学习下一课: