gpt4 book ai didi

What is the proper way to get status bar height in compose?(在写作中获得状态栏高度的正确方法是什么?)

转载 作者:bug小助手 更新时间:2023-10-24 19:24:15 27 4
gpt4 key购买 nike



Usually when using Accompanist Modifier.statusBarsHeight() the height will change depends on the status bar visibility, if it's visible either 24.dp or more and if it's invisible the height will be 0.dp. But i want the height won't change to zero regardless of its visibility.

通常,当使用伴奏Modifier.statusBarsHeight()时,高度将根据状态栏的可见性而改变,如果它是24.dp或更高的可见性,如果它不可见,高度将是0.dp。但我希望无论能见度如何,高度都不会更改为零。


I've been using this for a while:

我用这个已经有一段时间了:


// TODO: use better solution to get a fixed status bar height
val statusBarHeight = with (LocalDensity.current) { LocalWindowInsets.current.statusBars.top.toDp() }
val fixedStatusBarHeight = remember { statusBarHeight }

更多回答

What's wrong with your current code? Why you need remember here? In case status bar changes it would prevent you from getting an updated value

您当前的代码有什么问题?为什么你需要记住这里?如果状态栏发生更改,则会阻止您获取更新值

@PylypDukhov my composable padding would change if i don't use fixedStatusBarHeight when i hide the system bars, since the status bar height would be 0.dp

@PylypDukhov如果我在隐藏系统栏时不使用fixedStatusBarHeight,我的可组合填充将发生变化,因为状态栏高度将为0.dp

why do you want its height when status bar is invisible?

在状态栏不可见的情况下,为什么还要它的高度?

优秀答案推荐

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:

结果:


enter image description here



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不推荐自动导入,请尝试。有关更多详细信息,请阅读此答案。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com