软件编程
位置:首页>> 软件编程>> Android编程>> Jetpack Compose实现列表和动画效果详解

Jetpack Compose实现列表和动画效果详解

作者:大前端之旅  发布时间:2022-07-16 21:14:44 

标签:Jetpack,Compose,列表,动画

创建一个列表消息卡片

到目前为止,我们只有一个消息的卡片,看上去有点单调,所以让我们来改善它,让它拥有多条信息。我们需要创建一个能够显示多条消息的函数。对于这种情况,我们可以使用 Compose 的 LazyColumn 和 LazyRow。这些 Composable 只渲染屏幕上可见的元素,所以它们的设计对于长列表来说很有效果。同时,它们避免了 RecyclerView 与 XML 布局的复杂性。

import androidx.compose.foundation.lazy.items

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

@Composable
fun PreviewMessageCard() {
   ComposestudyTheme {
       Conversation(messages = MsgData.messages)
   }
}

你可以在这里获取 MsgData 的代码

MsgData.kt



object MsgData {
   private const val author = "大前端之旅"
   val messages = listOf(
       Message(author, "我们开始更新啦"),
       Message(author, "秋刀鱼会过期吗?"),
       Message(author, "下周就是端午了"),
       Message(author, "男人最好的状态是,25岁的时候能带着30岁的成熟去经营爱情,30岁的时候还带着18岁的不怕,去勇敢爱\uD83D\uDCAA"),
       Message(author, "Android之旅"),

   )
}

在这个代码片段中,你可以看到 LazyColumn 有一个 items 子项。它接收一个 List 作为参数,它的 lambda 接收一个我们命名为 message 的参数(我们可以随便命名)。 而这个 lambda 将会调用每个 List 中里面提供的 item。

Jetpack Compose实现列表和动画效果详解

可交互的动画效果

我们的对话越来越有趣了,是时候玩玩动画了! 我们将会实现当点击一个卡片查看详细内容的时候,使内容的大小和背景颜色都有动画效果。为了存储这个本地 UI 状态,我们需要跟踪一条消息是否已经展开了。为了跟踪这种状态变化,我们必须使用 remember 和 mutableStateOf 函数。

Composable 函数可以通过使用 remember 将本地状态存储在内存中,并跟踪传递给 mutableStateOf 的值的变化。当值被更新时,使用该状态的 Composable 函数(及其子函数)将被自动重新绘制。我们把这称为重组(recomposition)。

通过使用 Compose 的状态 API,如 remember 和 mutableStateOf,任何对状态的改变都会自动更新 UI。

@Composable
fun MessageCard(msg: Message) {

   var isExpanded by remember { mutableStateOf(false) } // 创建一个能够检测卡片是否被展开的变量

   Surface(
       shape = MaterialTheme.shapes.medium,
       elevation = 5.dp,
       modifier = Modifier
           .padding(all = 8.dp)
           .clickable { // 添加一个新的 Modifier 扩展方法,可以让元素具有点击的效果
               isExpanded = !isExpanded // 编写点击的事件内容
           }
   ) {
       Row(
           modifier = Modifier.padding(all = 8.dp)
       ) {
           Image(
               painterResource(id = R.drawable.profile_picture),
               contentDescription = "profile picture",
               modifier = Modifier
                   .size(50.dp)
                   .clip(CircleShape)
                   .border(1.5.dp, MaterialTheme.colors.secondary, shape = CircleShape)
           )
           Spacer(Modifier.padding(horizontal = 8.dp))
           Column {
               Text(
                   text = msg.author,
                   color = MaterialTheme.colors.secondaryVariant,
                   style = MaterialTheme.typography.subtitle2
               )
               Spacer(Modifier.padding(vertical = 4.dp))
               Text(
                   text = msg.body,
                   style = MaterialTheme.typography.body2,
                   // 修改 maxLines 参数,在默认情况下,只显示一行文本内容
                   maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                   // Composable 大小的动画效果
                   modifier = Modifier.animateContentSize()
               )
           }
       }
   }
}

Jetpack Compose实现列表和动画效果详解

现在我们已经能够完成每个卡片的检测了,让我们继续使用 isExpanded 来做点其他的事情吧!比如改变卡片的颜色

// 创建一个能够根据 isExpanded 变量值而改变颜色的变量
   val surfaceColor by animateColorAsState(
       targetValue = if (isExpanded) Color(0xFFCCCCCC) else MaterialTheme.colors.surface
   )

   Surface(
       shape = MaterialTheme.shapes.medium,
       elevation = 5.dp,
       modifier = Modifier
           .padding(all = 8.dp)
           .clickable {
               isExpanded = !isExpanded
           },
       color = surfaceColor
   ) {
       ...
       ...
   }

Jetpack Compose实现列表和动画效果详解

来源:https://juejin.cn/post/7104055633447485453

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com