Jetpack Compose中Scaffold内容调用fillMaxSize()无效果如何解决?
问题描述
我想要让Scaffold内容区域内的简短内容在屏幕上居中对齐,但给Scaffold的内容设置fillMaxSize()似乎完全没有生效,请问我该如何让该内容撑满全屏?
相关代码如下:
Scaffold实现代码
Scaffold( topBar = { }, floatingActionButtonPosition = FabPosition.End, floatingActionButton = { }, bottomBar = { } ) { paddingValues -> Column( modifier = Modifier .fillMaxSize() .verticalScroll(rememberScrollState()) .padding(paddingValues) ) { NavHost( navController = navController, startDestination = Screen.Running.route ) { composable(Screen.Business.route) { BusinessScreen(onSetAppTitle = { appTitle = it }) } ... } } }
BusinessScreen页面代码
@Composable fun BusinessScreen(onSetAppTitle: (String) -> Unit) { LaunchedEffect(Unit) { onSetAppTitle("Business Dashboard") } Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, modifier = Modifier .fillMaxSize() .background(Color.White) .padding(16.dp) ) { Text("Business Dashboard") } }
解决方案
该问题是布局约束传递异常导致的,核心原因有两点:
- 你给Scaffold内容区的Column加了
verticalScroll修饰符后,Column在垂直方向的布局约束变为无限大,此时fillMaxSize()在垂直方向没有固定边界可以匹配,会自动退化为适配内容高度的wrap模式。 - 嵌套在Column内的NavHost默认是自适应内容高度的,无法将固定高度约束传递给内部的BusinessScreen,所以页面里的
fillMaxSize()也无法生效,内容自然没法居中。
你可以根据实际需求选择以下两种修改方案:
场景1:需要保留内容区整体滚动能力
给NavHost添加fillParentMaxHeight()修饰符即可,这个修饰符是专门为滚动容器的子元素设计的,可以让子元素撑满滚动容器的可见视口高度,同时保留滚动能力。
同时需要注意Modifier的顺序,Scaffold传入的paddingValues需要先应用,再设置尺寸相关修饰符,避免布局计算异常。
修改后的Scaffold代码:
Scaffold( topBar = { }, floatingActionButtonPosition = FabPosition.End, floatingActionButton = { }, bottomBar = { } ) { paddingValues -> Column( modifier = Modifier .padding(paddingValues) // 先应用Scaffold的内边距避开上下栏 .fillMaxSize() .verticalScroll(rememberScrollState()) ) { NavHost( navController = navController, startDestination = Screen.Running.route, modifier = Modifier.fillParentMaxHeight() // 新增这行 ) { composable(Screen.Business.route) { BusinessScreen(onSetAppTitle = { appTitle = it }) } // 其他页面配置 } } }
场景2:不需要内容区整体滚动
直接删掉Column的verticalScroll修饰符即可,此时Column会正常撑满Scaffold的内容区,固定高度约束会一路传递到BusinessScreen,页面的fillMaxSize()会正常生效,内容会自动居中。
修改后的Scaffold代码:
Scaffold( topBar = { }, floatingActionButtonPosition = FabPosition.End, floatingActionButton = { }, bottomBar = { } ) { paddingValues -> Column( modifier = Modifier .padding(paddingValues) .fillMaxSize() // 删掉verticalScroll相关代码 ) { NavHost( navController = navController, startDestination = Screen.Running.route, modifier = Modifier.fillMaxSize() // 新增这行撑满父布局 ) { composable(Screen.Business.route) { BusinessScreen(onSetAppTitle = { appTitle = it }) } // 其他页面配置 } } }
两种方案修改后,BusinessScreen无需调整,内部的Text就会在内容区居中显示。
内容的提问来源于stack exchange,提问作者Raw Hasan
相关产品推荐
相关产品推荐

