Android 从XML动态获取状态栏高度
我需要优化我的Android应用程序,使其在手机上看起来更漂亮,比如基本手机 这款手机的状态栏高度与标准的25dp值不同,因此不能硬编码该值 昨天发布的Android p开发者预览版包括对notch的支持和一些用于查询其位置和边界的api,但对于我的应用程序,我只需要能够从XML获取状态栏高度,而不需要使用固定值 不幸的是,我找不到任何方法从XML中获取该值 有办法吗Android 从XML动态获取状态栏高度,android,android-layout,Android,Android Layout,我需要优化我的Android应用程序,使其在手机上看起来更漂亮,比如基本手机 这款手机的状态栏高度与标准的25dp值不同,因此不能硬编码该值 昨天发布的Android p开发者预览版包括对notch的支持和一些用于查询其位置和边界的api,但对于我的应用程序,我只需要能够从XML获取状态栏高度,而不需要使用固定值 不幸的是,我找不到任何方法从XML中获取该值 有办法吗 谢谢。方法提供状态栏的高度 public int getStatusBarHeight() { int result = 0
谢谢。方法提供状态栏的高度
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
我已经:
建议使用WindowInsets API,如下所示:
view.setOnApplyWindowInsetsListener { v, insets ->
view.height = insets.systemWindowInsetTop // status bar height
insets
}
访问状态栏高度,因为它是一种私人资源,因此在未来的Android版本中可能会发生变化,这是非常不鼓励的。这不是一个解决方案,但它可以解释如何正确使用状态栏高度,以及如何在引擎盖下运行: 旧解决方案: 这里有一个小技巧:
@*android:dimen/status_bar_height
android studio将向您显示一个错误,但它会像一个符咒一样工作:)我找到了一个解决方案,可以使用适合任何设备的状态栏大小。这是一种将大小从代码转换为XML布局的方法 解决方案是创建一个使用状态栏大小自动调整大小的视图。它就像来自约束布局的指南 我相信这应该是一个更好的方法,但我没有找到它。如果你考虑改进这个代码,请让我现在: 科特林
class StatusBarSizeView: View {
companion object {
// status bar saved size
var heightSize: Int = 0
}
constructor(context: Context):
super(context) {
this.init()
}
constructor(context: Context, attrs: AttributeSet?):
super(context, attrs) {
this.init()
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int):
super(context, attrs, defStyleAttr) {
this.init()
}
private fun init() {
// do nothing if we already have the size
if (heightSize != 0) {
return
}
// listen to get the height
(context as? Activity)?.window?.decorView?.setOnApplyWindowInsetsListener { _, windowInsets ->
// get the size
heightSize = windowInsets.systemWindowInsetTop
// return insets
windowInsets
}
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
// if height is not zero height is ok
if (h != 0 || heightSize == 0) {
return
}
// apply the size
postDelayed(Runnable {
applyHeight(heightSize)
}, 0)
}
private fun applyHeight(height: Int) {
// apply the status bar height to the height of the view
val lp = this.layoutParams
lp.height = height
this.layoutParams = lp
}
}
然后您可以在XML中使用它作为指南:
<com.foo.StatusBarSizeView
android:id="@+id/fooBarSizeView"
android:layout_width="match_parent"
android:layout_height="0dp" />
“heightSize”变量是公共变量,如果某些视图需要,可以在代码中使用它
也许这对其他人有帮助。您的构建可能会在任何稍微现代的版本的构建工具上失败,其中包含“错误:资源android:dimen/status\u bar\u height is private.”。@NPike No。它起作用了。但我同意这绝对不是最好的解决方案…@AndriyAntonov无构建错误,在android N,O上运行良好,但在Pt上运行不好。这在一个谷歌像素上对我有效,而在另一个具有完全相同操作系统的像素上,发布版本崩溃。不幸的是,此解决方案似乎不可靠,不应使用(op来自xml。在ios上有“安全”的布局指南。@skotos的回答对meThis很有效。我们使用Zoom SDK,他们在SDK中声明了这个确切的函数,只是有点不同-
if(resourceId<0)result=25.0f*context.getResources().getDisplayMetrics().density+0.5F;
。如果找不到像某些三星设备那样的resourceId,这将有所帮助。
class StatusBarSpacer @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
View(context, attrs) {
private var statusHeight: Int = 60
init {
if (context is Activity && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
context.window.decorView.setOnApplyWindowInsetsListener { _, insets ->
statusHeight = insets.systemWindowInsetTop
requestLayout()
insets
}
context.window.decorView.requestApplyInsets()
} else statusHeight = resources.getDimensionPixelSize(
resources.getIdentifier("status_bar_height", "dimen", "android")
)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) =
setMeasuredDimension(0, statusHeight)
}