1. 准备工作
在此 Codelab 中,您将学习如何使用 Jetpack Compose 在应用中创建可滚动列表。
您将使用 Affirmations 应用,该应用会显示配有精美图片的自我肯定话语列表,为您的日常生活带来满满正能量!
数据已经有了,您只需获取数据并将其显示在界面中即可。
前提条件
- 熟悉 Kotlin 中的列表
- 拥有使用 Jetpack Compose 构建布局的经验
- 拥有在设备或模拟器上运行应用的经验
学习内容
- 如何使用 Jetpack Compose 创建 Material Design 卡片?
- 如何使用 Jetpack Compose 创建可滚动列表?
构建内容
- 您将使用一个现有应用,在其界面中添加可滚动列表
完成后的效果将如下所示:
所需条件
- 一台连接到互联网并安装了网络浏览器和 Android Studio 的计算机
- 能够访问 GitHub
下载起始代码
在 Android Studio 中,打开 basic-android-kotlin-compose-training-affirmations
文件夹。
- 进入为此项目提供的 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 按钮 以构建并运行应用。请确保该应用按预期构建。
2. 创建列表项数据类
为 Affirmation 创建数据类
在 Android 应用中,列表由列表项组成。如果包含单项数据,列表项可以是字符串或整数等简单内容。对于包含多项数据的列表项(例如图片和文本),您需要一个包含所有这些属性的类。数据类是一种仅包含属性的类,可以提供一些可与这些属性配合使用的实用程序方法。
- 在 com.example.affirmations 下创建一个新的软件包。
将新软件包命名为 model。“model”软件包会包含将由一个数据类表示的数据模型。该数据类由表示“自我肯定话语”内容相关信息的属性组成;“自我肯定话语”将包含字符串资源和图片资源。软件包是包含类以及其他目录的目录。
- 在 com.example.affirmations.model 软件包中创建一个新类。
将新类命名为 Affirmation,并将其设为 Data Class。
- 每个
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. 向应用中添加列表
创建列表项卡片
此应用旨在显示自我肯定话语列表。将界面配置为显示列表的第一步是,创建列表项。每个自我肯定话语项都包含一张图片和一个字符串。每个项的数据都随附起始代码,您将创建界面组件来显示这样的项。
该项将由一个 Card
可组合项组成,后者包含一个 Image
和一个 Text
可组合项。在 Compose 中,Card
是一种在单个容器中显示内容和操作的 Surface。自我肯定话语卡片如下所示:
该卡片会显示一张图片并在其下方显示一些文本。这种垂直布局可以使用封装在 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
对象,并针对modifier
形参将padding
属性设置为8.dp
。为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
可组合项中包含的项会自行在界面中垂直排列。这样一来,您就可以在相关文本上方放置图片。相反,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 应用界面的核心,通过您的辛勤努力,它已经创建好了!如要检查卡片能否正确显示,您可以创建一个无需启动整个应用即可预览的可组合项。
- 创建一个名为
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))
}
- 打开 Split 标签页,您将看到
AffirmationCard
的预览。如有必要,请点击 Design 窗格中的 Build & Refresh,使系统显示预览。
创建列表
列表项组件是列表的构建块。创建列表项后,您可以利用它来创建列表组件。
- 创建一个名为
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。
- 在 Welcome to Android Studio 窗口中,点击 Open。
注意:如果 Android Studio 已经打开,则改为依次选择 File > Open 菜单选项。
- 在文件浏览器中,前往解压缩的项目文件夹所在的位置(很可能在 Downloads 文件夹中)。
- 双击该项目文件夹。
- 等待 Android Studio 打开项目。
- 点击 Run 按钮 以构建并运行应用。请确保该应用按预期构建。
5. 总结
现在,您已了解如何使用 Jetpack Compose 创建卡片、列表项和可滚动列表!请注意,这些只是用于创建列表的基本工具。您可以尽情挥洒创意,按自己的喜好自定义列表项!
总结
- 使用
Card
可组合项创建列表项。 - 修改
Card
可组合项中包含的界面。 - 使用
LazyColumn
可组合项创建可滚动列表。 - 使用自定义列表项构建列表。