Jetpack Compose 第 4 课:列表和动画

点击查看:Jetpack Compose 教程
点击查看:Composetutorial 代码

简介

Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代码、强大的工具和直观的 Kotlin API,可以帮助您简化并加快 Android 界面开发。

在本教程中,您将使用声明性的函数构建一个简单的界面组件。您无需修改任何 XML 布局,也不需要使用布局编辑器。相反,您只需调用可组合函数来定义所需的元素,Compose 编译器即会完成后面的所有工作。

列表和动画

列表和动画在应用内随处可见。在本课中,您将学习如何利用 Compose 轻松创建列表并添加有趣的动画效果。

效果图

Jetpack Compose 第 4 课:列表和动画_第1张图片

创建消息列表

只包含一条消息的聊天略显孤单,因此我们将更改对话,使其包含多条消息。您需要创建一个可显示多条消息的 Conversation 函数。对于此用例,请使用 Compose 的 LazyColumn 和 LazyRow。这些可组合项只会呈现屏幕上显示的元素,因此,对于较长的列表,使用它们会非常高效。

在此代码段中,您可以看到 LazyColumn 包含一个 items 子项。它接受 List 作为参数,并且其 lambda 会收到我们命名为 message 的参数(可以随意为其命名),该参数是 Message 的实例。简而言之,系统会针对提供的 List 的每个项调用此 lambda。将示例数据集复制到您的项目中,以便快速引导对话。

在展开消息时显示动画效果

对话变得更加有趣了。是时候添加动画效果了!您将添加展开消息以显示更多内容的功能,同时为内容大小和背景颜色添加动画效果。为了存储此本地界面状态,您需要跟踪消息是否已展开。为了跟踪这种状态变化,您必须使用 remember 和 mutableStateOf 函数。

可组合函数可以使用 remember 将本地状态存储在内存中,并跟踪传递给 mutableStateOf 的值的变化。该值更新时,系统会自动重新绘制使用此状态的可组合项(及其子项)。这称为重组。

通过使用 Compose 的状态 API(如 remember 和 mutableStateOf),系统会在状态发生任何变化时自动更新界面。

注意: 您需要添加以下导入内容才能正确使用 Kotlin 的委托属性语法(by 关键字)。按 Alt+Enter 键或 Option+Enter 键即可添加这些内容。
import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue

现在,您可以根据点击消息时消息的 isExpanded 状态,更改消息内容的背景颜色。您将使用 clickable 修饰符来处理可组合项上的点击事件。您会为背景颜色添加动画效果,使其值逐步从 MaterialTheme.colorScheme.surface 更改为 MaterialTheme.colorScheme.primary(反之亦然),而不只是切换 Surface 的背景颜色。为此,您将使用 animateColorAsState 函数。最后,您将使用 animateContentSize 修饰符顺畅地为消息容器大小添加动画效果:

Base04.kt代码

package com.example.composetutorial.activity

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.example.composetutorial.R
import com.example.composetutorial.ui.theme.ComposeTutorialTheme

/*
https://developer.android.google.cn/jetpack/compose/tutorial
第 4 课:列表和动画
创建消息列表
只包含一条消息的聊天会略显孤单,因此请更改对话,使其包含多条消息。您需要创建一个可显示多条消息的 Conversation 函数。对于此用例,请使用 Compose 的 LazyColumn 和 LazyRow。这些可组合项只会呈现屏幕上显示的元素,因此,对于较长的列表,使用它们会非常高效。

在此代码段中,您可以看到 LazyColumn 包含一个 items 子项。它接受 List 作为参数,并且其 lambda 会收到我们命名为 message 的参数(可以随意为其命名),它是 Message 的实例。简而言之,系统会针对提供的 List 的每个项调用此 lambda。将此示例数据集导入您的项目,以便快速引导对话。




在展开消息时显示动画效果
对话变得更加有趣了。是时候添加动画效果了!您将添加展开消息以显示更多内容的功能,同时为内容大小和背景颜色添加动画效果。为了存储此本地界面状态,您需要跟踪消息是否已展开。为了跟踪这种状态变化,您必须使用 remember 和 mutableStateOf 函数。

可组合函数可以使用 remember 将本地状态存储在内存中,并跟踪传递给 mutableStateOf 的值的变化。该值更新时,系统会自动重新绘制使用此状态的可组合项(及其子项)。这称为重组。

通过使用 Compose 的状态 API(如 remember 和 mutableStateOf),系统会在状态发生任何变化时自动更新界面。

注意:您需要添加以下导入内容才能正确使用 by。按 Alt+Enter 键或 Option+Enter 键即可添加这些内容。
import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue

现在,您可以根据 isExpanded 更改点击消息时的消息内容的背景。您将使用 clickable 修饰符来处理可组合项上的点击事件。您会为背景颜色添加动画效果,使其值逐步从 MaterialTheme.colors.surface 更改为 MaterialTheme.colors.primary(反之亦然),而不只是切换 Surface 的背景颜色。为此,您将使用 animateColorAsState 函数。最后,您将使用 animateContentSize 修饰符顺畅地为消息容器大小添加动画效果:


 */
class Base04 :ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTutorialTheme {
                val msgs = mutableListOf<Message4>()
                for (index in 0 .. 30){
                    msgs.add(Message4("Test ${index}","描述内容 ${index} import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue 现在,您可以根据 isExpanded 更改点击消息时的消息内容的背景。您将使用 clickable 修饰符来处理可组合项上的点击事件。您会为背景颜色添加动画效果"))
                }

                Conversation(msgs)
            }
        }

    }
}

data class Message4(val author: String, val body: String)


@Composable
fun MessageCard(msg: Message4) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.mipmap.icon_nav_mine),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colors.secondaryVariant, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colors.secondaryVariant,
                style = MaterialTheme.typography.subtitle2
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                elevation = 1.dp,
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.body2
                )
            }
        }
    }
}


@Composable
fun Conversation(messages: List<Message4>) {
    LazyColumn {
        items(messages) { message ->
            MessageCard(message)
        }
    }
}

你可能感兴趣的:(#,JetpackCompose,android,jetpack,android)