博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android获取状态栏高度、标题栏高度、编辑区域高度
阅读量:6156 次
发布时间:2019-06-21

本文共 4483 字,大约阅读时间需要 14 分钟。

一、Activity界面的划分

   

 简单说明一下(上图Activity采用默认Style,状态栏和标题栏都会显示):最大的草绿色区域是屏幕界面,红色次大区域我们称之为“应用程序界面区域”,最小紫色的区域我们称之为“View绘制区域”;屏幕顶端、应用界面区之外的那部分显示手机电池网络运营商信息的为“状态栏”,应用区域顶端、View绘制区外部显示Activity名称的部分我们称为“标题栏”。

二、状态高度的测量

        状态栏是显示显示手机状态(如电池电量、网络状态、时间、运营商信息等)的区域,一般内容型应用都会显示保留状态栏,但是游戏界面如果还保留状态栏就不合适了,因为游戏界面要响应各种手势,而状态栏也会响应一些手势,有可能引发错误操作,所以一般在游戏界面都会隐藏状态栏,使游戏界面全屏显示,关于设置全屏请查看 ,继续看状态栏高度测量:
        状态栏高度的测量我在这里提供4种方法:

      (1)通过系统尺寸资源获取

        状态栏高度定义在Android系统尺寸资源中status_bar_height,但这并不是公开可直接使用的,例如像通常使用系统资源那样android.R.dimen.status_bar_height。但是系统给我们提供了一个Resource类,通过这个类可以获取资源文件,借此可以获取到status_bar_height
/** * 获取状态栏高度——方法1 * */  int statusBarHeight1 = -1;  //获取status_bar_height资源的ID  int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");  if (resourceId > 0) {      //根据资源ID获取响应的尺寸值      statusBarHeight1 = getResources().getDimensionPixelSize(resourceId);  }  Log.e("-------", "状态栏-方法1:" + statusBarHeight1)
(2)通过R类的反射
        大家都知道Android的所有资源都会有惟一标识在R类中作为引用。我们也可以通过反射获取R类的实例域,然后找status_bar_height
/**  * 获取状态栏高度——方法2  * */   int statusBarHeight2 = -1;   try {      Class
clazz = Class.forName("com.android.internal.R$dimen"); Object object = clazz.newInstance(); int height = Integer.parseInt(clazz.getField("status_bar_height") .get(object).toString()); statusBarHeight2 = getResources().getDimensionPixelSize(height); } catch (Exception e) { e.printStackTrace(); } Log.e("-------", "状态栏-方法2:" + statusBarHeight2);

(3)借助应用区域的top属性

        这就用到了开题时的那张屏幕区域划分图片,状态栏位于屏幕最顶端,其位置从(0,0)开始,故而应用区域的顶端位置(高度 = Y坐标 - 0)即为状态栏的高度
/** * 获取状态栏高度——方法3 * 应用区的顶端位置即状态栏的高度 * *注意*该方法不能在初始化的时候用 * */  Rect rectangle= new Rect();  getWindow().getDecorView().getWindowVisibleDisplayFrame(rectangle);  //高度为rectangle.top-0仍为rectangle.top  Log.e("-------", "状态栏-方法3:" + rectangle.top);
*注意* 
如果单单获取statusBar高度而不获取titleBar高度时,这种方法并不推荐大家使用,因为这种方法依赖于WMS(窗口管理服务的回调)。正是因为窗口回调机制,所以在Activity初始化时执行此方法得到的高度是0,这就是很多人获取到statusBar高度为0的原因。这个方法推荐在回调方法onWindowFocusChanged()中执行,才能得到预期结果

       (4)借助屏幕和应用区域高度

        还是看屏幕区域划分图,是不是状态栏占满了屏幕中除应用区域之外的全部呢?所以直接上代码
/** * 获取状态栏高度——方法4 * 状态栏高度 = 屏幕高度 - 应用区高度 * *注意*该方法不能在初始化的时候用 * */  //屏幕  DisplayMetrics dm = new DisplayMetrics();  getWindowManager().getDefaultDisplay().getMetrics(dm);  //应用区域  Rect outRect1 = new Rect();  getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1);  int statusBar = dm.heightPixels - outRect1.height();  //状态栏高度=屏幕高度-应用区域高度  Log.e("------------", "状态栏-方法4:" + statusBar);

       3、4这两种方法其实本质是一样,所以如果单单获取statusBar高度而不获取titleBar高度时也不推荐大家使用,理由同上方法3

 三、标题栏高度的测量

        搞懂了上边的原理,标题栏高度的测量也就手到擒来啦,依旧是屏幕区域划分图。这里也给出两种方法,先给出公共代码吧,就是获取各区域(*注意*依旧是在Activity的回调方法onWindowFocusChanged()中执行,才能得到预期结果)
//屏幕          DisplayMetrics dm = new DisplayMetrics();          getWindowManager().getDefaultDisplay().getMetrics(dm);          Log.e("-------", "屏幕高:" + dm.heightPixels);            //应用区域          Rect outRect1 = new Rect();          getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1);          Log.e("------", "应用区顶部" + outRect1.top);          Log.e("-------", "应用区高" + outRect1.height());                    //View绘制区域          Rect outRect2 = new Rect();          getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(outRect2);           Log.e("--------", "View绘制区域顶部-错误方法:" + outRect2.top);   //不能像上边一样由outRect2.top获取,这种方式获得的top是0,可能是bug吧          int viewTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();   //要用这种方法          Log.e("--------", "View绘制区域顶部-正确方法:" + viewTop);          Log.e("--------", "View绘制区域高度:" + outRect2.height());

有时候获取View绘制区时列出来的那个outRect2.top=0

(1)top-top

/** * 获取标题栏高度-方法1 * 标题栏高度 = View绘制区顶端位置 - 应用区顶端位置(也可以是状态栏高度,获取状态栏高度方法3中说过了) * */  int titleHeight1 = viewTop - outRect1.top;  Log.e("--------", "标题栏高度-方法1:" + titleHeight1);

(2)高度-高度

/** * 获取标题栏高度-方法2 * 标题栏高度 = 应用区高度 - View绘制区高度  * */  int titleHeight2 = outRect1.height() - outRect2.height();  Log.e("----------", "标题栏高度-方法2:" + titleHeight2);

       四、注意事项

        *注意* 

        (1)不管你是否设置全屏模式,或是不显示标题栏,在使用获取状态栏高度方法1和获取状态栏高度方法2都会测量到状态栏的高度,理解原理就不难解释——系统资源属性是固定的、真实的,不管你是否隐瞒(隐藏或者显示),它都在那里;

        (2)但是若使用获取状态栏高度方法3和获取状态栏高度方法4,以及获取标题栏高度方法1和获取标题栏高度方法2,都是依赖于WMS,是在界面构建后根据View获取的,所以显示了就有高度,不显示自然没高度了。

    下面是验证

    先设置Activity为全屏

 

        屏幕各区域获取不变;

 

        输出StatusBar和titleBar高度信息

int titleHeight1 = viewTop - outRect1.top;  Log.e("--------", "验证Statue高度:" + titleHeight1);  Log.e("--------", "验证Title高度:" + outRect1.top);

 

 

转载于:https://www.cnblogs.com/developer-wang/p/6771073.html

你可能感兴趣的文章
JAVA GC
查看>>
3springboot:springboot配置文件(外部配置加载顺序、自动配置原理,@Conditional)
查看>>
前端第七天
查看>>
图解SSH原理及两种登录方法
查看>>
【总结整理】JQuery基础学习---样式篇
查看>>
查询个人站点的文章、分类和标签查询
查看>>
基础知识:数字、字符串、列表 的类型及内置方法
查看>>
JSP的隐式对象
查看>>
JS图片跟着鼠标跑效果
查看>>
[SCOI2005][BZOJ 1084]最大子矩阵
查看>>
学习笔记之Data Visualization
查看>>
Leetcode 3. Longest Substring Without Repeating Characters
查看>>
416. Partition Equal Subset Sum
查看>>
app内部H5测试点总结
查看>>
[TC13761]Mutalisk
查看>>
while()
查看>>
常用限制input的方法
查看>>
IIS7下使用urlrewriter.dll配置
查看>>
并行程序设计学习心得1——并行计算机存储
查看>>
bulk
查看>>