Compose 中 共享元素动画

388 阅读2分钟

在 Jetpack Compose 中,共享元素动画(Shared Element Transition)是一种常见的动画效果,用于在两个界面之间实现元素的平滑过渡。这种动画效果通常用于在两个界面之间共享相同的元素,例如在列表界面中点击某个元素,然后在详情界面中展示相同元素的详细信息,并通过动画使得元素在两个界面之间平滑过渡。

实现步骤

实现共享元素动画的一般步骤如下:

  1. 在起始界面准备共享元素

    • 在起始界面中,准备好需要共享的元素,并为其设置一个唯一的 transitionName。
  2. 启动共享元素动画

    • 在起始界面中,通过 Navigation 或 Intent 启动目标界面,并传递共享元素的 transitionName。
  3. 在目标界面接收共享元素

    • 在目标界面中,接收传递过来的 transitionName,并为目标元素设置相同的 transitionName。
  4. 设置共享元素过渡动画

    • 在目标界面中,使用 androidx.compose.material3.Surface 组件的 Modifier.semantics 属性来设置共享元素过渡动画。

示例代码

以下是一个简单的示例代码,演示了如何在 Jetpack Compose 中实现共享元素动画:

起始界面:

import androidx.compose.material3.Text
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController

@Composable
fun StartScreen(navController: NavController) {
    var selectedElement by remember { mutableStateOf("") }

    Column(
        modifier = Modifier.padding(16.dp)
    ) {
        Button(onClick = {
            selectedElement = "sharedElement"
            navController.navigate("destination_screen")
        }) {
            Text("Go to Destination")
        }

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

        Text(text = "Selected Element: $selectedElement")
    }
}

@Preview
@Composable
fun StartScreenPreview() {
    StartScreen(rememberNavController())
}

目标界面:

import androidx.compose.material3.Surface
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun DestinationScreen(selectedElement: String) {
    Surface(
        modifier = Modifier
            .fillMaxSize()
            .semantics(mergeDescendants = true) {
                sharedElement(selectedElement)
            }
    ) {
        Column(
            modifier = Modifier.padding(16.dp)
        ) {
            Text(text = "Destination Screen")
            Spacer(modifier = Modifier.height(16.dp))
            Text(text = "Shared Element: $selectedElement")
        }
    }
}

@Preview
@Composable
fun DestinationScreenPreview() {
    DestinationScreen("sharedElement")
}

解释

  1. 起始界面:

    • 在起始界面中,我们定义了一个按钮,当点击按钮时,我们将 selectedElement 的值设置为 "sharedElement",并通过 NavController 导航到目标界面。
  2. 目标界面:

    • 在目标界面中,我们使用 Surface 组件的 Modifier.semantics 属性来设置共享元素过渡动画,将 selectedElement 作为共享元素的 transitionName。

通过以上步骤,我们可以在 Jetpack Compose 中实现共享元素动画,使得元素在起始界面和目标界面之间实现平滑过渡,并提升用户体验。