我们可以在每个屏幕上有一个没有功能缺点的 NavigationBar 实例吗?

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

使用 Jetpack Compose 和 Material Design 时,是否可以在每个屏幕上使用新的

NavigationBar
(又名
BottomNavigationBar
)?或者这会中断例如触摸动画作为新的
NavigationBar
在切换屏幕时被实例化?

我的想法是,这真的可以很容易地在某些屏幕上隐藏或显示

NavigationBar
,而不是在其他屏幕上(而不是与层次结构中更高的
Scaffold
进行通信)

android android-jetpack-compose navigationbar bottom-navigation-bar
1个回答
0
投票

BottomNavigation
composable 没有什么特别之处,您可以在下面的源代码中看到它

@Composable
fun BottomNavigation(
    modifier: Modifier = Modifier,
    backgroundColor: Color = MaterialTheme.colors.primarySurface,
    contentColor: Color = contentColorFor(backgroundColor),
    elevation: Dp = BottomNavigationDefaults.Elevation,
    content: @Composable RowScope.() -> Unit
) {
    Surface(
        color = backgroundColor,
        contentColor = contentColor,
        elevation = elevation,
        modifier = modifier
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .height(BottomNavigationHeight)
                .selectableGroup(),
            horizontalArrangement = Arrangement.SpaceBetween,
            content = content
        )
    }
}

在每个屏幕上调用

BottomNavigation
类似于在任何屏幕上使用另一个可组合项。此外,
BottomNavigationItem
只是一个
Box
或两个
Box
es 当标签和图标都存在时动画 alpha 和标签偏移的进度。

@Composable
fun RowScope.BottomNavigationItem(
    selected: Boolean,
    onClick: () -> Unit,
    icon: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    label: @Composable (() -> Unit)? = null,
    alwaysShowLabel: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    selectedContentColor: Color = LocalContentColor.current,
    unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)
) {
    val styledLabel: @Composable (() -> Unit)? = label?.let {
        @Composable {
            val style = MaterialTheme.typography.caption.copy(textAlign = TextAlign.Center)
            ProvideTextStyle(style, content = label)
        }
    }
    // The color of the Ripple should always the selected color, as we want to show the color
    // before the item is considered selected, and hence before the new contentColor is
    // provided by BottomNavigationTransition.
    val ripple = rememberRipple(bounded = false, color = selectedContentColor)

    Box(
        modifier
            .selectable(
                selected = selected,
                onClick = onClick,
                enabled = enabled,
                role = Role.Tab,
                interactionSource = interactionSource,
                indication = ripple
            )
            .weight(1f),
        contentAlignment = Alignment.Center
    ) {
        BottomNavigationTransition(
            selectedContentColor,
            unselectedContentColor,
            selected
        ) { progress ->
            val animationProgress = if (alwaysShowLabel) 1f else progress

            BottomNavigationItemBaselineLayout(
                icon = icon,
                label = styledLabel,
                iconPositionAnimationProgress = animationProgress
            )
        }
    }
}

或者这会打断例如触摸动画作为新的 NavigationBar 在切换屏幕时被实例化?

这取决于调用的动画类型,因为当屏幕进入组合时,新的 BottomNavigation 可组合项将在每个屏幕上调用。

如果你有一个动画,当一个项目被点击时开始,例如,需要一秒钟才能完成,在新页面上,你可能会看到目标索引在目标页面中被选中,而你可能希望这个动画继续,因为它只在一页。

@Composable
fun BottomNavigationComponent() {
    var selectedIndex by remember { mutableStateOf(1) }
    val tabContents = listOf(
        "Home" to Icons.Filled.Home,
        "Map" to Icons.Filled.Map,
        "Settings" to Icons.Filled.Settings
    )

    BottomNavigation(
        backgroundColor = MaterialTheme.colors.surface,
        contentColor = MaterialTheme.colors.onSurface,
        elevation = 2.dp
    ) {
        tabContents.forEachIndexed { index, pair: Pair<String, ImageVector> ->
            BottomNavigationItem(
                icon = { Icon(pair.second, contentDescription = null) },
                label = { Text(pair.first) },
                selected = selectedIndex == index,
                alwaysShowLabel = false, // Hides the title for the unselected items
                onClick = {
                    selectedIndex = index
                }
            )
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.