我需要优化我的Android应用,以便在具有缺陷的手机上看起来很好,例如Essential Phone。
此手机的状态栏高度与标准25dp值不同,因此您无法对该值进行硬编码。
昨天发布的Android P开发者预览包括支持缺口和一些API查询其位置和边界,但对于我的应用程序,我只需要能够从XML获取状态栏高度,而不是使用固定值
不幸的是,我找不到任何方法从XML中获取该值。
有什么办法吗?
谢谢。
答案 0 :(得分:7)
我已经found the answer:
推荐的方法是使用WindowInsets API,如下所示:
view.setOnApplyWindowInsetsListener { v, insets ->
view.height = insets.systemWindowInsetTop // status bar height
insets
}
非常不鼓励访问status_bar_height,因为它是私有资源,因此可能会在未来版本的Android中发生变化。
答案 1 :(得分:3)
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)
}
答案 2 :(得分:2)
方法提供状态栏的高度
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
答案 3 :(得分:2)
这不是一个解决方案,但它可以解释你应该如何以正确的方式进行操作以及如何进行操作: https://www.youtube.com/watch?v=_mGDMVRO3iE
OLD SOLUTION:
这是一个小技巧:
@*android:dimen/status_bar_height
android studio会显示错误,但它会像魅力一样工作:)
答案 4 :(得分:0)
我找到了一种解决方案,可以使用适合任何设备的状态栏大小。这是一种将大小从代码转换为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”变量是公用的,如果某些视图需要它,可以在代码中使用它。
也许对其他人有帮助。