android android沉浸式状态栏 - 状态栏的高度?



(9)

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

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

谢谢


Answers

我建议下一个代码:

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)Device 1品牌:samsung,设备:maguro,board:tuna,cpu_abi:armeabi-v7a,显示:ICL53F.M420KREL08,制造商:samsung,型号:Galaxy Nexus,ver。发行:4.0.2,ver.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;

设备1在屏幕顶部有标题栏,状态栏在屏幕底部有软件按钮。

2)设备2设备:bravo,board:bravo,cpu_abi:armeabi-v7a,display:FRG83G,制造商:HTC,型号:HTC Desire,ver。发行:2.2.2,ver.sdk:8,

屏幕分辨率:800 x 400.此设备具有硬件按钮。

结果:

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)

B) display.getHeight() - v.getHeight() 

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

变体:

 display.getHeight() - v.getBottom() + rect.top

在这两种情况下给出正确的结果

更新

3)还有一个例子(第三个设备):品牌:LGE,设备:v909,cpu_abi:armeabi-v7a,显示:HMJ37,型号:LG-V909,ver.release:3.1,ver.sdk: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。


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("*** Jorgesys :: ", "StatusBar Height= " + StatusBarHeight + " , TitleBar Height = " + TitleBarHeight); 

获取Activity的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;
} 

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

phoneBarsHeight = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight() 
    - mainView.getHeight();

你可以把它放在onGlobalLayout() 。 这也适用于平板电脑,我在Theme.NoTitleBar上试过它,但它必须始终有效。

也许你甚至可以通过将mainView.getHeight()更改为mainView.getHeight()来增强它并在onCreate()使用它。


您还可以使用here描述的方式获取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方法中将runnable附加到您的一个视图,并将上面的代码放在那里。 这将导致应用程序在连接到屏幕时计算状态栏+标题屏幕高度。

看看下面的代码:

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并添加毫秒值作为第二个参数。


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

我从here找到了这个代码,它在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;
}

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


从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,直到View已附加到Window,因此它不能直接在onCreate()但您可以为窗口附加添加一个侦听器并在那里执行 - 这里我添加了状态栏插入我的工具栏大小,我隐藏和显示,以及状态栏。 当它显示时,我想要状态栏在它的顶部,所以我将状态栏高度添加到工具栏的顶部填充。

    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+开始使用WindowInsets类:

customView.setOnApplyWindowInsetsListener((view, insets) -> {
    // Handle insets
    return insets.consumeSystemWindowInsets();
});

或支持库的WindowInsetsCompat

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的演讲 - 成为主窗口钳工here提供幻灯片)。


如果你有一个复选框,你想在任何java文件中获取它的值,例如true / false--

使用 -

Context mContext;
boolean checkFlag;

checkFlag=PreferenceManager.getDefaultSharedPreferences(mContext).getBoolean(KEY,DEFAULT_VALUE);`




android