安卓通知栏和标题栏的大小是多少?

27

有没有办法在Android中获取通知栏和标题栏的大小?目前,我通过以下方式获取显示宽度和高度:

Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();

之后,我想减去条形的大小,这样我就可以在不失去纵横比的情况下拉伸视频。目前我隐藏了这些条形,因为我找不到更好的方法。

8个回答

20

也许这是一个有帮助的方法:参考图标设计指南,根据屏幕密度,状态(通知)栏只有三种不同的高度:

  • 对于LDPI,高度为24px
  • 对于MDPI,高度为32px
  • 对于HDPI,高度为48px

因此,如果使用DisplayMetrics中的densityDpi检索设备的屏幕密度,就可以知道要减去哪个值。

所以代码看起来可能像这样:

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int myHeight = 0;

    switch (metrics.densityDpi) {
        case DisplayMetrics.DENSITY_HIGH:
            Log.i("display", "high");
            myHeight = display.getHeight() - 48;
            break;
        case DisplayMetrics.DENSITY_MEDIUM:
            Log.i("display", "medium/default");
            myHeight = display.getHeight() - 32;
            break;
        case DisplayMetrics.DENSITY_LOW:
            Log.i("display", "low");
            myHeight = display.getHeight() - 24;
            break;
        default:
            Log.i("display", "Unknown density");

这看起来很有前途。我试图实现它,但即使densityDpi在javadoc中被声明公共,我在Eclipse中也无法访问它...使用density似乎不是一个选择,因为javadoc说:“这个值并不完全遵循真实的屏幕大小”。 - lalalei
谢谢!我没有意识到在Android 1.5中不可用metrics.densityDpi。现在我将我的项目更改为使用1.6,它可以工作了!我只改变了一件事:我将值乘以2,例如display.getHeight() - 48 * 2。通过这样做,我减去了标题栏和通知栏的高度。希望这对其他设备也适用。我刚在Nexus上测试过。 - lalalei
我认为应该这样,因为规范是这么说的 - 如果您能点击左侧的勾号接受答案,那就太好了 :) - DonGru
通知栏高度为24dp。 - sergey.n

19

据我所知,这完全有效。

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

1
这个程序可以正常工作,而且这是在所有屏幕尺寸下了解确切大小的最佳选择。谢谢。 - Pelanes

18
Martin的答案指定的高度是错误的(至少在SDKv11之后是这样)。根据图标设计指南,状态栏图标的高度为25dp,而不是32dp。25dp转换为以下密度特定的高度:
  • LDPI为19px
  • MDPI为25px
  • HDPI为38px
  • XHDPI为50px
观察这些大小的简单方法是使用hierarchyviewer来查看具有正常密度的模拟器或设备。只需查看标题栏的FrameLayout的getHeight()值即可。状态栏有点棘手,因为它是DecorView的一部分,而不是一个单独的视图,所以通过间接查看标题栏的FrameLayout的mTop来获取其高度,该FrameLayout紧贴着状态栏下方。从我的观察中可以得出,状态栏和标题栏都与状态栏图标的25dp高度匹配(截至SDKv11,我没有在android文档中看到这个事实的声明)。

3

我使用以下代码获取高度:

对于状态(通知)栏:

View decorView = getWindow().getDecorView();
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;

标题栏:

View contentView = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
int[] location = new int[2];
contentView.getLocationInWindow(location);
int titleBarHeight = location[1] - statusBarHeight;

1

嗨,我认为这不是必要的,如果您使用VideoView,它将自动完成。

VideoView vv = (VideoView) findViewById(R.id.MainVideo);                        
    MediaController mc=new MediaController(this);
    mc.setEnabled(true);
    mc.show(0);
    vv.setMediaController(mc); 
    vv.setVideoURI(Uri.parse(URLMedia));
    vv.requestFocus();
    vv.showContextMenu();
    vv.start();         

我使用SurfaceView而不是VideoView,因为我实现了不同的控件UI(我需要音量控制和全屏切换按钮)。我不使用MediaController。 - lalalei

0

这比硬编码值要好得多,因为Android仍然会返回在特定设备上状态栏或操作栏的高度值,即使它们可能不可见。

因此,想法是获取内容视图,所有视图都添加到其中。

public View getContentView(Activity a) {
        int id = a.getResources().getIdentifier("content", "id", "android");
        return a.findViewById(id);
    }

然后,在你的活动中

View cView = getContentView(this);
cView.post(()->{ 
int offsetY = cView.getTop(); 
// do whatever here.
});

以上代码的好处是它也会考虑到操作栏。

0

抱歉,这是一个愚蠢的评论,但使用常量作为通知栏高度是不正确的。 只需获取全局视图(PhoneWindow$DecorView),然后获取其子视图(它将仅有一个视图(FrameLayout))。此布局包含您的应用程序视图并测量整个屏幕(请参见FrameLayout.mHeight)。其中第一个布局将是您的第一个视图,因此获取其top将给您正确的通知栏高度。在没有上下文的情况下使用FrameLayout将毫无意义,因为在这种情况下,您的子项的顶部将等于0。

对于懒惰的人:

ViewGroup decoreView = (ViewGroup)*YourActivityViewHere*.getRootView();
int barSize = ((ViewGroup)decoreView.getChildAt(0)).getChildAt(0).getTop();

你也可以使用

getWindow().getDecorView().getRootView()

使用你的活动视图代替


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接