The problem is getting complicated you should use it like this
问题变得复杂了,你应该这样使用它
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Box(
modifier = Modifier
.fillMaxSize()
.statusBarsPadding().navigationBarsPadding()
) {
}
Box(
modifier = Modifier
.fillMaxSize()
.statusBarsPadding().systemBarsPadding()
) {
}
}
}
}
So i ended up making a workaround alongside with a modifier extension for easier use.
因此,我最终做了一个变通办法,同时增加了一个修饰符扩展以便于使用。
First, make a data class to hold the fixed inset values.
首先,创建一个数据类来保存固定的插入值。
data class FixedInsets(
val statusBarHeight: Dp = 0.dp,
val navigationBarsPadding: PaddingValues = PaddingValues(),
)
Second, create the extension and a composition local provider.
其次,创建扩展和组合本地提供程序。
val LocalFixedInsets = compositionLocalOf<FixedInsets> { error("no FixedInsets provided!") }
@Composable
fun Modifier.fixedStatusBarsPadding(): Modifier {
return this.padding(top = LocalFixedInsets.current.statusBarHeight)
}
@Composable
fun Modifier.fixedNavigationBarsPadding(): Modifier {
return this.padding(paddingValues = LocalFixedInsets.current.navigationBarsPadding)
}
Finally, provide the fixed inset values at the very root of your composable function.
最后,在可组合函数的最底层提供固定的插入值。
val systemBarsPadding = WindowInsets.systemBars.asPaddingValues()
val fixedInsets = remember {
FixedInsets(
statusBarHeight = systemBarsPadding.calculateTopPadding(),
navigationBarsPadding = PaddingValues(
bottom = systemBarsPadding.calculateBottomPadding(),
start = systemBarsPadding.calculateStartPadding(LayoutDirection.Ltr),
end = systemBarsPadding.calculateEndPadding(LayoutDirection.Ltr),
),
)
}
CompositionLocalProvider(
values = arrayOf(
LocalFixedInsets provides fixedInsets,
),
) {
MainScreen()
}
Navigation bar padding example:
导航栏填充示例:
Text(
text = "Hello i'm a text with navigation bar padding",
modifier = Modifier
.fillMaxSize()
.background(color = Color.Red)
.fixedNavigationBarsPadding(),
)
Or you can access the sizes in Dp
directly from the local composition by using calculateXPadding()
:
或者,您可以使用culateXPding()直接从本地合成访问DP中的大小:
val fixedInsets = LocalFixedInsets.current
Text(
text = "The navigation bar's height is: ${fixedInsets.navigationBarsPadding.calculateBottomPadding()}",
)
Currently, there is an ExperimentalLayoutApi that provides statusBarsIgnoringVisibility
.
目前,有一个试验性的LayoutApi,它提供了statusBarsIGnoringVisibility。
Example use case:
使用案例示例:
I have two screens, A and B. Screen A uses statusBarsIgnoringVisibility
for top padding. In screen B, you can hide the status bar (e.g., full screen photo). When going from screen B to screen A, I want the top padding in screen A to already equal the full height of the status bar while the status bar comes back into view. Without statusBarsIgnoringVisibility
, this transition doesn't look very good.
我有两个屏幕,一个是A屏幕,一个是B屏幕。屏幕A使用statusBarsIGnoingVivision作为顶部填充。在屏幕B中,您可以隐藏状态栏(例如,全屏照片)。当从屏幕B转到屏幕A时,我希望屏幕A中的顶部填充已经等于状态栏的完全高度,同时状态栏重新进入视图。如果没有statusBarsIGnoringVisibility,这种转换看起来并不是很好。
For TopAppBar
, the following code works for getting its height:
对于TopAppBar,以下代码可用于获取其高度:
import androidx.compose.runtime.*
...
...
@Composable
fun TopAppBarComposable(){
var topAppBarHeight by remember {mutableStateOf(0.dp)}
val localDensity = LocalDensity.current
TopAppBar(
modifier = Modifier
.onGloballyPositioned { layoutCoordinates ->
with(localDensity){
topAppBarHeight = layoutCoordinates.size.height.toDp()
}
}
)
You can use WindowInsets.statusBars.getTop(this)
您可以使用WindowInsets.statusBars.getTop(This)
For example (map takes all screen - behind status and navigation bar):
例如(MAP采用所有屏幕后状态和导航栏):
GoogleMap(
modifier = Modifier.fillMaxSize(),
cameraPositionState = cameraPositionState,
properties = MapProperties(isMyLocationEnabled = true),
contentPadding = with(LocalDensity.current) {
PaddingValues(
top = WindowInsets.statusBars.getTop(this).toDp(),
bottom = WindowInsets.navigationBars.getBottom(this).toDp()
)
}
) {
Result:
结果:
Here's how I set it, I get the height of the status bar from Resources
下面是我如何设置它的,我从参考资料中获得状态栏的高度
fun getStatusBarHeight(): Int {
val resources = Resources.getSystem()
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
return resources.getDimensionPixelSize(resourceId)
}
@Composable
fun Modifier.paddingBarHeight() = composed {
padding(top = remember { getStatusBarHeight() })
}
更多回答
Works perfectly for me! Correct answer!
对我来说太棒了!答对了!
but it doesn't give the height as value (in dp for example), to use with GoogleMap(contentPadding = PaddingValues()
for example, so your answer works only for specific cases, it's not universal
但它并没有将高度作为值(例如在dp中),例如与GoogleMap(contentPadding = PaddingValues())一起使用,因此您的答案仅适用于特定情况,它不是通用的
Depending on the case you will need the exact exact height of the status bar and navigation bar. But I haven't seen a case where it has to be resolved that way. I've tried getting their sizes and that would be costly to the system's memory. If you try to do it in the compose functions, the performance of the app will drop
根据具体情况,您需要精确的状态栏和导航栏的高度。但我还没有见过必须以这种方式解决的案例。我试过获取它们的尺寸,但这会耗费系统的内存。如果您尝试在编写函数中执行此操作,应用程序的性能将会下降
I used your approach for getting soft navigatoin bar height...but it always gives me zero values... i.imgur.com/n2tAHNx.png
我使用了你的方法来获得软导航栏高度…但它总是给我零值…I.imgur.com/n2tAHNx.png
this solution is not working
这个解决方案不起作用
in the topAppBarHeight var, when assigning a value, this happen: > Type 'MutableState<Dp>' has no method 'setValue(Nothing?, KProperty<*>, Dp)' and thus it cannot serve as a delegate for var (read-write property)
在topAppBarHeight var中,赋值时会发生这种情况:>类型‘MuableState’没有方法‘setValue(Nothing?,KProperty<*>,dp)’,因此它不能用作var(读写属性)的委托
@MarlonLópez Add import androidx.compose.runtime.*
manually and then try, if Android Studio doesn't recommend this import automatically. For more details you can read this answer.
@MarLonLópez手动添加导入androidx.compose.untime*,如果Android Studio不推荐自动导入,请尝试。有关更多详细信息,请阅读此答案。
我是一名优秀的程序员,十分优秀!