Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/247.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 状态栏的高度?_Android - Fatal编程技术网

Android 状态栏的高度?

Android 状态栏的高度?,android,Android,有没有办法获得状态栏+标题栏的高度?查看dev论坛显示了相同的问题,但没有解决方案(我可以找到) 我知道我们可以在初始布局通过后获得它,但我希望在活动的onCreate()中获得它 谢谢 获取活动的onCreate()方法上状态栏的高度,请使用以下方法: public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_h

有没有办法获得状态栏+标题栏的高度?查看dev论坛显示了相同的问题,但没有解决方案(我可以找到)

我知道我们可以在初始布局通过后获得它,但我希望在活动的onCreate()中获得它

谢谢

获取活动的
onCreate()
方法上状态栏的高度,请使用以下方法:

public int getStatusBarHeight() { 
      int result = 0;
      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
      } 
      return result;
} 

将runnable附加到onCreate方法中的一个视图,并将上面的代码放在其中。这将导致应用程序在连接到屏幕时计算状态栏+标题屏幕高度

请看下面的代码:

myView.post(new Runnable() {

        @Override
        public void run() {
            Rect rectgle= new Rect();
            Window window= getWindow();
            window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
            int StatusBarHeight= rectgle.top;
            int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
            int TitleBarHeight= contentViewTop - StatusBarHeight;

        }

    });

如果这仍然不起作用,请尝试调用视图的postDelayed方法,而不是post,并添加毫秒值作为第二个参数

我认为更好的计算方法是计算全屏的高度减去主布局

phoneBarsHeight = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight() 
    - mainView.getHeight();
您可以将其放入
onGlobalLayout()
。这也适用于平板电脑,我在Theme.NoTitleBar上试用过,但它必须始终有效


也许您甚至可以通过将
mainView.getHeight()
更改为
mainView.getmeasuredeheight()
来增强它并使用它
onCreate()
,我建议下一个代码:

Rect rect = new Rect();
Window window = activity.getWindow();
if (window != null) {
  window.getDecorView().getWindowVisibleDisplayFrame(rect);
  android.view.View v = window.findViewById(Window.ID_ANDROID_CONTENT);

  android.view.Display display = ((android.view.WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

  //return result title bar height
  return display.getHeight() - v.getBottom() + rect.top;   
}
两个例子:

1) 设备1 品牌:三星, 设备:马古罗, 董事会:金枪鱼, cpu_abi:armeabi-v7a, 显示:ICL53F.M420KREL08, 制造商:三星, 型号:Galaxy Nexus, 版本:4.0.2, sdk版本:14

屏幕分辨率:1280 x 720。此设备上没有硬件按钮

结果:

rect: left=0 right=720 top=72 bottom=1208;
v: left=0 right=720 top=72 bottom=1208;
display: height=1208 width=720;
correct result=72;
rect: left=0 right=480 top=38 bottom=800;
v: left=0 right=480 top=0 bottom=800;
display: height=800 width=480;
correct result: phone_bar_height=38;
设备1的标题栏位于屏幕顶部,状态栏的软件按钮位于屏幕底部

2) 装置2 装置:好极了, 董事会:太好了, cpu_abi:armeabi-v7a, 显示器:FRG83G, 制造商:HTC, 型号:HTC Desire, 版本发布:2.2.2, sdk版本:8

屏幕分辨率:800 x 400。这个设备有硬件按钮

结果:

rect: left=0 right=720 top=72 bottom=1208;
v: left=0 right=720 top=72 bottom=1208;
display: height=1208 width=720;
correct result=72;
rect: left=0 right=480 top=38 bottom=800;
v: left=0 right=480 top=0 bottom=800;
display: height=800 width=480;
correct result: phone_bar_height=38;
设备2在屏幕顶部有标题栏,但根本没有状态栏

上文提出了两种解决办法:

A) v.getTop() - rect.top 
设备1不正确-它给出的是0而不是72)

这对于设备2不正确-它给出的是0而不是38)

变体:

 display.getHeight() - v.getBottom() + rect.top
在这两种情况下都给出了正确的结果

更新

3) 另一个示例(第三个设备): 品牌:LGE, 设备:v909, cpu_abi:armeabi-v7a, 显示器:HMJ37, 型号:LG-V909, 版本:3.1, 版本:12

rect: left=0 right=1280 top=0 bottom=720
v: left=0 right=1280 top=0 bottom=720
Display: height=768 width=1280
phone_bar_height=48
设备3具有水平方向,在屏幕顶部没有标题栏,在屏幕底部有状态栏

因此,这里:

int size_of_title_bar = rect.top;
int size_of_status_bar = display.getHeight() - v.getBottom();

这对于设备2和3是正确的。我对设备1没有把握。用户向我发送了设备1的屏幕截图。那里有一个带有软件按钮的状态栏。但是表达式“display.getHeight()-v.getBottom()”给出0

您还可以使用描述的方式获取android的dimens.xml文件中的状态栏维度

这可以获得状态栏的高度,而无需等待绘图

引用博客文章中的代码:

public int getStatusBarHeight() {
  int result = 0;
  int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
  if (resourceId > 0) {
      result = getResources().getDimensionPixelSize(resourceId);
  }
  return result;
}

您需要将此方法放入ContextWrapper类。

虽然这是一个老问题,但我发现在
onCreate()中答案不起作用。

我在
onCreate()
方法中找到了这段代码

public int getStatusBarHeight() {
   int result = 0;
   int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
   if (resourceId > 0) {
      result = getResources().getDimensionPixelSize(resourceId);
   }
   return result;
}

我希望这对任何遇到这个问题的人都有帮助。

Jorgesys发布的解决方案非常好,但它在onCreate()方法中不起作用。 我想这是因为状态栏和标题栏是在onCreate()之后创建的

解决方案很简单-您应该将代码放在runnable中,并在onCreate()之后使用
root.post((runnable操作))执行它

因此,整个解决方案:

root = (ViewGroup)findViewById(R.id.root);
root.post(new Runnable() { 
        public void run(){
            Rect rectgle= new Rect();
            Window window= getWindow();
            window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
            int StatusBarHeight= rectgle.top;
            int contentViewTop= 
                 window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
            int TitleBarHeight= contentViewTop - StatusBarHeight;

            Log.i("***  jakkubu :: ", "StatusBar Height= " + StatusBarHeight +
               " , TitleBar Height = " + TitleBarHeight);
        }
});

对于像我这样希望在XML布局中使用它的人,我发现它:

<...
  android:layout_marginTop="@*android:dimen/status_bar_height"
  ... />


不要被Android Studio(2.2预览版3——在撰写本文时)不支持这个概念所迷惑。运行时会这样做。我是从谷歌的源代码中获取的。

从API 23开始,有一个更好的解决方案来获取状态栏的高度。API 23添加了一个
WindowInsets
功能,因此您可以使用此代码获取系统插入的大小,在本例中为顶部

public int getStatusBarHeight() {
    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        return binding.mainContent.getRootWindowInsets().getStableInsetTop();
    }
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if(resourceId != 0) {
        return getResources().getDimensionPixelSize(resourceId);
    }
    return 0;
}
请注意,
getRootWindowInsets()
将返回null,直到视图被附加到窗口之后,因此它不能直接用于
onCreate()
中,但您可以为窗口附加添加一个侦听器并在那里执行此操作-在这里,我将状态栏inset添加到我的工具栏的大小,我将隐藏并显示它,以及状态栏。显示时,我希望状态栏位于其顶部,因此我将状态栏高度添加到工具栏的顶部填充中

    binding.mainContent.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
        @Override
        public void onViewAttachedToWindow(View view) {
            binding.toolbar.setPadding(binding.toolbar.getPaddingLeft(),
                binding.toolbar.getPaddingTop() + getStatusBarHeight(),
                binding.toolbar.getPaddingRight(), binding.toolbar.getPaddingBottom());
            binding.mainContent.removeOnAttachStateChangeListener(this);
        }

        @Override
        public void onViewDetachedFromWindow(View view) {

        }
    });

获取状态栏高度的支持方式是使用从API 21+开始的类:

customView.setOnApplyWindowInsetsListener((view, insets) -> {
    // Handle insets
    return insets.consumeSystemWindowInsets();
});
或支持库:

ViewCompat.setOnApplyWindowInsetsListener(customView, (view, insets) -> {
    // Handle insets
    return insets.consumeSystemWindowInsets();
});
您还可以在视图中覆盖onApplyWindowInsets的
方法:

public class CustomView extends View {
    @Override
    public WindowInsets onApplyWindowInsets(final WindowInsets insets) {
        final int statusBarHeight = insets.getStableInsetTop();
        return insets.consumeStableInsets();
    }
}

要了解更多详细信息,我建议查看Chris Banes talk-成为主窗口装配工(幻灯片可用)。

这可能看起来不相关,但大多数情况下,人们寻找状态栏高度的原因是为了偏移自己的视图,以便不将其放置在状态栏下

通过在视图上设置
fitsystemwindows
,您希望“按下”状态栏以给状态栏留出空间,它将根据每个设备上状态栏的大小自动完成。填充将添加到将此属性设置为
true
的视图中

请记住,填充只会添加到层次结构中的第一个视图中,
fitSystemWindows
设置为
true

例如,这适用于状态栏为半透明的情况。确保为未设置
fitSystemWindows
的活动设置主题,否则填充将添加到活动中(因为它是hie中的第一个)
protected void onCreate(Bundle savedInstanceState) {
     ...
     setContentView(R.layout.activity_main);
     ....
     // Use The topmost view of the activity, which 
    // is guaranteed to be asked about window insets/
     View rootView = findViewById(R.id.root_view_of_your_activity);
     ViewCompat.setOnApplyWindowInsetsListener(rootView, new OnApplyWindowInsetsListener() {
        @Override
        public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) 
    {
        //THIS is the value you want.
        statusBarHeight = insets.getSystemWindowInsetTop();

        // Let the view handle insets as it likes.
        return ViewCompat.onApplyWindowInsets(v,insets);
    }
});
class MyActivity : ViewBindingActivity<LayoutBinding>() {
...

    override fun created(binding: LayoutBinding, savedInstanceState: Bundle?) {

        binding.root.setOnApplyWindowInsetsListener { _, insets ->
            val statusBarHeight = insets.getInsets(WindowInsets.Type.statusBars()).top // <- HERE YOU ARE
            val toolbarHeight = getDimenPx(R.dimen.toolbar_height)
            binding.toolbar.layoutParams.height = statusBarHeight + toolbarHeight
            insets
        }
    }
}