Android Jetpack Compose 和 voyager 在屏幕之间传递 topBar 高度和导航栏高度

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

我正在使用 jetpack compose 开发一个应用程序,在将内容定位在顶部栏和底部导航栏之间留下的空间内时遇到了问题,我正在寻找一种在屏幕之间发送高度的方法用作填充物。

在我的 MainActivity 中,我使用自定义 AppBar 和 voyager 导航栏,屏幕内容位于它们之间。

class MainActivity : ComponentActivity() {


    companion object {
        var navigationHeight = mutableStateOf(0.dp)
        var topAppBarHeight = mutableStateOf(0.dp)
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        R2DroidApplication.defaultEnvironment.initEnvironment()
        super.onCreate(savedInstanceState)
        setContent {
            Rr2DroidDynamicTheme {
                Content()
            }
        }
    }

    @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
    @Composable
    fun Content() {
        TabNavigator(HomeTab) {
            Scaffold(
                content = {
                    CurrentTab()
                },
                topBar = {
                    AppBar(title = stringResource(id = R.string.app_name), canGoBack = false,
                        modifier = Modifier.onGloballyPositioned { layoutCoordinates ->
                            topAppBarHeight.value = layoutCoordinates.size.height.dp
                        })
                },
                bottomBar = {
                    NavigationBar(modifier = Modifier.onGloballyPositioned { layoutCoordinates ->
                        navigationHeight.value = layoutCoordinates.size.height.dp
                    }) {
                        TabNavigationItem(tab = HomeTab)
                        TabNavigationItem(tab = PackageManagerTab)
                    }
                }
            )
        }
    }

    @Composable
    private fun RowScope.TabNavigationItem(tab: Tab) {
        val tabNavigator = LocalTabNavigator.current

        NavigationBarItem(
            selected = tabNavigator.current.key == tab.key,
            alwaysShowLabel = true,
            label = { Text(text = tab.options.title) },
            onClick = { tabNavigator.current = tab },
            icon = { Icon(painter = tab.options.icon!!, contentDescription = tab.options.title) }
        )
    }

}

我的AppBar是一个简单的Box,其中包含一个CenterAlignedTopBar和一个用于显示进度的线性进度条:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppBar(title: String, canGoBack: Boolean = true, contentLoaded: Boolean = false, modifier: Modifier = Modifier) {
    val navigator = LocalNavigator.currentOrThrow

    Box() {
        Column() {
            CenterAlignedTopAppBar(
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor = LocalDynamicThemeState.current.colorTuple.value.surface!!,
                    titleContentColor = LocalDynamicThemeState.current.colorTuple.value.primary,
                ),
                title = {
                    Text(title)
                },
                navigationIcon = {
                    if (canGoBack) {
                        IconButton(onClick = {navigator.pop()}) {
                            Icon(
                                painter = painterResource(id = R.drawable.back),
                                contentDescription = stringResource(id = R.string.back)
                            )
                        }
                    }
                }
            )
            IndeterminateLinearIndicator(isLoading = contentLoaded)
            Divider()
        }
    }
}

@Composable
fun IndeterminateLinearIndicator(isLoading: Boolean = false) {
    var loading by remember { mutableStateOf(isLoading) }

    if (!loading) return

    LinearProgressIndicator(
        modifier = Modifier.fillMaxWidth(),
        color = MaterialTheme.colorScheme.secondary,
        trackColor = MaterialTheme.colorScheme.surfaceVariant,
    )
}

我的屏幕内容呈现在选项卡中

object PackageManagerTab : Tab {

    val packageManagerScreen = PackageManagerScreen()
    override val options: TabOptions
        @Composable
        get() {
            val title = stringResource(R.string.package_manager)
            val icon = rememberVectorPainter(image = FeatherIcons.Package)

            return remember {
                TabOptions(
                    index = 0u,
                    title = title,
                    icon = icon
                )
            }
        }

    @Composable
    override fun Content() {
        Box() {
            packageManagerScreen.Content()
        }
    }
}

屏幕是一个简单的 BottomSheetScaffold,包含内容和工作表内容。

我该如何进行?

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

开箱即用的

Scaffold
可组合项将
PaddingValues
参数传递给
content
可组合项。此参数保存应应用于
content
的填充,以确保
content
不与
topBar
bottomBar
重叠。

Scaffold(
    content = { innerPadding ->  // parameter containing top and bottom padding
        CurrentTab(modifier = Modifier.padding(innerPadding))
    },
    topBar = {
        //...
    },
    bottomBar = {
        //...
    }
)

还要更新您的

CurrentTab
可组合项,以将传入的修饰符应用到第一个嵌套可组合项:

@Composable
fun CurrentTab(aModifier: Modifier) {
    Column(
        modifier = aModifier
    ) {
        //...
    }
}

旁注:
另请检查模块的 build.gradle 文件中的依赖项。因为相当长一段时间以来,您都会收到编译器错误:

Jetpack Compose:未使用内容填充参数

这可能表明您正在使用相当不推荐使用的组件。

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