如何在 Jetpack Compose 中创建带有动画打开和关闭的动画底部导航栏

问题描述 投票:0回答:1

我正在使用 Jetpack Compose 开发 Android 应用程序,我想实现一个底部导航栏,其中的菜单可以以流畅的动画打开和关闭。

底部的导航栏应该有多个图标,当点击某个图标时,应该出现一个带有动画的菜单(例如淡入或上滑动画)。当按下关闭图标时,菜单还应该以反向动画关闭。

主要要求是:

具有多个项目的底部导航栏。 单击特定项目时会以动画打开的菜单。 触发时菜单应以动画关闭。 在 Jetpack Compose 中实现此目标的最佳方法是什么?我应该使用 AnimatedVisibility、BottomSheetScaffold 还是其他东西?

bottom bar with menu

谢谢您的帮助!

android kotlin android-jetpack-compose android-jetpack compose-multiplatform
1个回答
0
投票

实现此行为的主要步骤如下。

  1. 创建一个包含多个项目的简单底部导航栏。
  2. 管理当前所选项目的状态和动画菜单的可见性。
  3. 使用 AnimatedVisibility 为菜单的打开和关闭设置动画。

将此视为您的菜单:

@Composable
fun MenuContent(onClose: () -> Unit) {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.Gray)
            .padding(16.dp)
    ) {
        Text("Menu Item 1")
        Text("Menu Item 2")
        Text("Menu Item 3")

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

        Button(onClick = onClose) {
            Text("Close")
        }
    }
}

其余实施:

@Composable
fun BottomNavWithMenu() {
    var isMenuVisible by remember { mutableStateOf(false) }
    var selectedItem by remember { mutableStateOf(BottomNavItem.Home) }

    Scaffold(
        bottomBar = {
            BottomNavigation() {
                BottomNavItem.values().forEach { item ->
                    BottomNavigationItem(
                        icon = { Icon(item.icon, contentDescription = item.contentDescription) },
                        label = { Text(item.label) },
                        selected = selectedItem == item,
                        onClick = {
                            if (item == BottomNavItem.More) {
                                isMenuVisible = !isMenuVisible // Toggle menu visibility
                            } else {
                                selectedItem = item
                                isMenuVisible = false // Close menu if another item is clicked
                            }
                        }
                    )
                }
            }
        }
    ) { padding ->
        Box(modifier = Modifier.padding(padding).fillMaxSize()) {
            MainContent(selectedItem)

            AnimatedVisibility(
                visible = isMenuVisible,
                enter = fadeIn() + slideInVertically(initialOffsetY = { it }),
                exit = fadeOut() + slideOutVertically(targetOffsetY = { it }),
                modifier = Modifier.align(Alignment.BottomCenter)
            ) {
                MenuContent(onClose = { isMenuVisible = false })
            }
        }
    }
}

@Composable
fun MainContent(selectedItem: BottomNavItem) {
    // Your main content based on selectedItem
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Text(text = "Selected Item: ${selectedItem.label}")
    }
}

enum class BottomNavItem(val label: String, val icon: @Composable () -> Unit, val contentDescription: String) {
    Home("Home", { Icon(Icons.Filled.Home, null) }, "Home"),
    Search("Search", { Icon(Icons.Filled.Search, null) }, "Search"),
    More("More", { Icon(Icons.Filled.MoreHoriz, null) }, "More")
}

主要概念是关于导航栏项目单击事件和自定义菜单的动画可见性。

© www.soinside.com 2019 - 2024. All rights reserved.