1. 开始之前
在本 Codelab 中,您将学习如何使用 Jetpack Compose 在应用中创建可滚动列表。
您将使用 Affirmations 应用,该应用显示一系列搭配精美图片的励志格言,为您的日常生活带来积极能量!
数据已经准备就绪,您只需获取这些数据并在 UI 中显示即可。
先决条件
- 熟悉 Kotlin 中的列表
- 使用 Jetpack Compose 构建布局的经验
- 在设备或模拟器上运行应用的经验
您将学到什么
- 如何使用 Jetpack Compose 创建 Material Design 卡片
- 如何使用 Jetpack Compose 创建可滚动列表
您将构建什么
- 您将获取现有应用程序并在 UI 中添加可滚动列表
最终产品将如下所示
您需要什么
- 一台连接互联网的电脑、一个网络浏览器和 Android Studio
- 访问 GitHub
下载起始代码
在 Android Studio 中,打开 basic-android-kotlin-compose-training-affirmations
文件夹。
- 导航到项目提供的 GitHub 存储库页面。
- 验证分支名称是否与 Codelab 中指定的分支名称匹配。例如,在以下屏幕截图中,分支名称为 main。
- 在项目的 GitHub 页面上,点击 Code 按钮,这将弹出一个弹出窗口。
- 在弹出窗口中,点击 Download ZIP 按钮将项目保存到您的电脑。等待下载完成。
- 找到电脑上的文件(可能在 Downloads 文件夹中)。
- 双击 ZIP 文件以解压缩。这将创建一个包含项目文件的新文件夹。
在 Android Studio 中打开项目
- 启动 Android Studio。
- 在 欢迎使用 Android Studio 窗口中,点击 打开。
注意:如果 Android Studio 已经打开,则选择 文件 > 打开 菜单选项。
- 在文件浏览器中,导航到解压缩的项目文件夹所在的目录(可能在您的 Downloads 文件夹中)。
- 双击该项目文件夹。
- 等待 Android Studio 打开项目。
- 点击 运行 按钮 以构建并运行应用。确保应用按预期构建。
2. 创建列表项数据类
为 Affirmation 创建数据类
在 Android 应用中,列表由列表项组成。对于单个数据片段,这可能很简单,例如字符串或整数。对于包含多个数据片段的列表项(如图像和文本),您将需要一个包含所有这些属性的类。数据类是一种仅包含属性的类,它们可以提供一些实用方法来处理这些属性。
- 在 com.example.affirmations 下创建一个新包。
将新包命名为 model。model 包将包含由数据类表示的数据模型。该数据类将由表示与“Affirmation”相关信息的属性组成,这些信息将包含字符串资源和图像资源。包是包含类甚至其他目录的目录。
- 在 com.example.affirmations.model 包中创建一个新类。
将新类命名为 Affirmation 并将其设为 数据类。
- 每个
Affirmation
由一个图像和一个字符串组成。在Affirmation
数据类中创建两个val
属性。一个应命名为stringResourceId
,另一个应命名为imageResourceId
。它们都应为整数。
Affirmation.kt
data class Affirmation(
val stringResourceId: Int,
val imageResourceId: Int
)
- 使用
@StringRes
注解标记stringResourceId
属性,并使用@DrawableRes
标记imageResourceId
。stringResourceId
表示存储在字符串资源中的励志格言文本的 ID。imageResourceId
表示存储在可绘制资源中的励志格言图像的 ID。
Affirmation.kt
data class Affirmation(
@StringRes val stringResourceId: Int,
@DrawableRes val imageResourceId: Int
)
- 现在打开 com.example.affirmations.data 包中的
Datasource.kt
文件,并取消注释Datasource
类的内容。
Datasource.kt
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))
}
}
3. 向应用添加列表
创建列表项卡片
此应用旨在显示一系列励志格言。配置 UI 以显示列表的第一步是创建列表项。每个励志格言项包含一个图像和一个字符串。每个项目的这些数据都随起始代码一起提供,您将创建 UI 组件以显示此类项目。
该项目将由一个 Card
可组合项组成,其中包含一个 Image
和一个 Text
可组合项。在 Compose 中, Card
是一个表面,用于在一个容器中显示内容和操作。Affirmation 卡片将如下所示
卡片显示一个图像,下方有一些文本。可以使用包含在 Card
可组合项中的 Column
可组合项实现此垂直布局。您可以自己尝试一下,也可以按照以下步骤操作。
- 打开 MainActivity.kt 文件。
- 在
AffirmationApp()
方法下方创建一个新方法,命名为AffirmationCard()
,并使用@Composable
注解进行注释。
MainActivity.kt
@Composable
fun AffirmationApp() {
val context = LocalContext.current
AffirmationsTheme {
}
}
@Composable
fun AffirmationCard() {
}
- 编辑方法签名以将
Affirmation
对象作为参数。Affirmation
对象来自model
包。
MainActivity.kt
@Composable
fun AffirmationCard(affirmation: Affirmation) {
}
- 向签名中添加一个
modifier
参数。为参数设置一个默认值Modifier
。
MainActivity.kt
@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
}
- 在
AffirmationCard
方法内部,调用Card
可组合项。传入以下参数:modifier
和elevation
。为modifier
参数传入一个带有padding
属性设置为8.dp
的Modifier
对象。为elevation
传入值4.dp
。elevation
属性将在后面详细介绍。
MainActivity.kt
@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {Card(modifier = modifier.padding(8.dp), elevation = 4.dp) {
}
}
- 在
Card
可组合项内部添加一个Column
可组合项。Column
可组合项中的项目在 UI 中垂直排列。这使您可以将图像放置在关联文本的上方。相反,Row
可组合项会水平排列其包含的项目。
MainActivity.kt
@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
Card(modifier = modifier.padding(8.dp), elevation = 4.dp) {
Column {
}
}
}
- 在
Column
可组合项的 lambda 主体内部添加一个Image
可组合项。请记住,Image
可组合项始终需要一个要显示的资源和一个contentDescription
。该资源应为传递给painter
参数的painterResource
。painterResource
方法将加载矢量可绘制对象或诸如 PNG 之类的栅格化资产格式。此外,为contentDescription
参数传入一个stringResource
。
MainActivity.kt
@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
Card(modifier = Modifier.padding(8.dp), elevation = 4.dp) {
Column {
Image(
painter = painterResource(affirmation.imageResourceId),
contentDescription = stringResource(affirmation.stringResourceId)
)
}
}
}
- 除了
painter
和contentDescription
参数外,还可以传入modifier
和contentScale
。contentScale
确定如何缩放和显示图像。Modifier
对象应具有设置为fillMaxWidth
的属性和高度194.dp
。contentScale
应为ContentScale.Crop
。
MainActivity.kt
@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
Card(modifier = Modifier.padding(8.dp), elevation = 4.dp) {
Column {
Image(
painter = painterResource(affirmation.imageResourceId),
contentDescription = stringResource(affirmation.stringResourceId),
modifier = Modifier
.fillMaxWidth()
.height(194.dp),
contentScale = ContentScale.Crop
)
}
}
}
- 在
Column
内部,在Image
可组合项之后创建一个Text
可组合项。将affirmation.stringResourceId
的stringResource
传递给text
参数,传递一个具有padding
属性设置为16.dp
的Modifier
对象,并通过将MaterialTheme.typography.h6
传递给style
参数来设置文本主题。
MainActivity.kt
@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
Card(modifier = Modifier.padding(8.dp), elevation = 4.dp) {
Column {
Image(
painter = painterResource(affirmation.imageResourceId),
contentDescription = stringResource(affirmation.stringResourceId),
modifier = Modifier
.fillMaxWidth()
.height(194.dp),
contentScale = ContentScale.Crop
)
Text(
text = stringResource(affirmation.stringResourceId),
modifier = Modifier.padding(16.dp),
style = MaterialTheme.typography.h6
)
}
}
}
预览 AffirmationCard 可组合项
卡片是 Affirmations 应用 UI 的核心,您已经努力创建了它!为了检查卡片是否显示正确,您可以创建一个可组合项,该可组合项可以在不启动整个应用的情况下进行预览。
- 创建一个名为
AffirmationCardPreview()
的私有方法。使用@Preview
和@Composable
注解该方法。
MainActivity.kt
@Preview
@Composable
private fun AffirmationCardPreview() {
}
- 在方法内部,调用
AffirmationCard
可组合项,并向其传递一个新的Affirmation
对象,并将R.string.affirmation1
字符串资源和R.drawable.image1
可绘制资源传递到其构造函数中。
MainActivity.kt
@Preview
@Composable
private fun AffirmationCardPreview() {
AffirmationCard(Affirmation(R.string.affirmation1, R.drawable.image1))
}
- 打开“拆分”选项卡,您将看到
AffirmationCard
的预览。如有必要,请在“设计”窗格中单击“构建并刷新”以显示预览。
创建列表
列表项组件是列表的基础构建块。创建列表项后,您可以利用它来创建列表组件本身。
- 创建一个名为
AffirmationList()
的方法,使用@Composable
注解它,并在方法签名中声明一个Affirmation
对象的List
作为参数。
MainActivity.kt
@Composable
private fun AffirmationList(affirmationList: List<Affirmation>) {
}
- 在方法签名中声明一个
modifier
对象作为参数,其默认值为Modifier
。
MainActivity.kt
@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
}
- 在 Jetpack Compose 中,可以使用
LazyColumn
可组合项创建可滚动列表。LazyColumn
和Column
之间的区别在于,当您要显示少量项目时,应使用Column
,因为 Compose 会一次性加载所有项目。Column
只能容纳预定义或固定的数量的可组合项。LazyColumn
可以根据需要添加内容,这使其非常适合长列表,尤其是在列表长度未知时。LazyColumn
还默认提供滚动功能,无需额外代码。在AffirmationList()
方法内部声明一个LazyColumn
可组合项。
MainActivity.kt
@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
LazyColumn {
}
}
- 在
LazyColumn
的 lambda 体中,调用items()
方法,并将affirmationList
传递进去。items()
方法是将项目添加到LazyColumn
的方法。此方法对于此可组合项来说有些独特,在大多数可组合项中并不是常见的做法。
MainActivity.kt
@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
LazyColumn {
items(affirmationList){
}
}
}
items()
方法的调用需要一个 lambda 函数。在该函数中,指定一个名为affirmation
的参数,该参数表示来自affirmationList
的一个肯定项。
MainActivity.kt
@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
LazyColumn {
items(affirmationList){ affirmation ->
}
}
}
- 对于列表中的每个肯定项,调用
AffirmationCard()
可组合项,并将affirmation
传递给它。
MainActivity.kt
@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
LazyColumn {
items(affirmationList){ affirmation ->
AffirmationCard(affirmation)
}
}
}
显示列表
- 在 lambda 中,调用
AffirmationList
可组合项,并将DataSource().loadAffirmations()
传递给affirmationList
参数。
MainActivity.kt
@Composable
fun AffirmationApp() {
AffirmationsTheme {
Scaffold(
content = {
AffirmationList(affirmationList = Datasource().loadAffirmations())
}
)
}
}
在设备或模拟器上运行 Affirmations 应用,查看最终产品!
4. 获取解决方案代码
如果要查看解决方案代码,请在 GitHub 上查看。
- 导航到项目提供的 GitHub 存储库页面。
- 验证分支名称是否与 Codelab 中指定的分支名称匹配。例如,在以下屏幕截图中,分支名称为 main。
- 在项目的 GitHub 页面上,点击 Code 按钮,这将弹出一个弹出窗口。
- 在弹出窗口中,点击 Download ZIP 按钮将项目保存到您的电脑。等待下载完成。
- 找到电脑上的文件(可能在 Downloads 文件夹中)。
- 双击 ZIP 文件以解压缩。这将创建一个包含项目文件的新文件夹。
在 Android Studio 中打开项目
- 启动 Android Studio。
- 在 欢迎使用 Android Studio 窗口中,点击 打开。
注意:如果 Android Studio 已经打开,则选择 文件 > 打开 菜单选项。
- 在文件浏览器中,导航到解压缩的项目文件夹所在的目录(可能在您的 Downloads 文件夹中)。
- 双击该项目文件夹。
- 等待 Android Studio 打开项目。
- 点击 运行 按钮 以构建并运行应用。确保应用按预期构建。
5. 结论
您现在知道了如何使用 Jetpack Compose 创建卡片、列表项和可滚动列表!请记住,这些只是创建列表的基本工具。您可以发挥您的创造力,随意自定义列表项!
摘要
- 使用
Card
可组合项创建列表项。 - 修改
Card
可组合项内包含的 UI。 - 使用
LazyColumn
可组合项创建可滚动列表。 - 使用自定义列表项构建列表。