一、Activity界面的划分

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

二、状态高度的测量

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

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

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

 

<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

屏幕各区域获取不变;

输出StatusBar和titleBar高度信息

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

Android获取状态栏高度、标题栏高度、编辑区域高度的更多相关文章

  1. Android获取状态栏和标题栏的高度

    版权声明:本文为博主原创文章,未经博主允许不得转载. 1.获取状态栏高度: decorView是window中的最顶层view,可以从window中获取到decorView,然后decorView有个 ...

  2. Android获取状态栏的高度:

    方法一: //获取手机状态栏高度 public static int getStatusBarHeight(Context context){ Class<?> c = null; Obj ...

  3. android获取状态栏高度

    获取android屏幕上状态栏的高度方法网上很多这里不再敖述,只举一个例子 Rect rect = new Rect();getWindow().getDecorView().getWindowVis ...

  4. Android 中状态栏、标题栏、View的大小及区分

    1.获得状态栏的高度(状态栏相对Window的位置): Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisp ...

  5. Android隐藏状态栏和标题栏,相当于全屏效果

    隐藏标题栏需要使用预定义样式:android:theme=”@android:style/Theme.NoTitleBar”. 隐藏状态栏:android:theme=”@android:style/ ...

  6. Android之获取屏幕的尺寸像素及获取状态栏标题栏高度

    在Android的实际开发中,会经常用到获取屏幕的尺寸的问题,以便设置一些布局在屏幕上的固定位置,从而适配各个屏幕的设备. 今天我就来讲一下怎么得到当前设备的屏幕像素吧: 一.在Activity中: ...

  7. android获取自己定义控件位置坐标,屏幕尺寸,标题栏,状态栏高度

    android获取自己定义控件位置坐标,屏幕尺寸,标题栏,状态栏高度 1.获取自己定义控件height 在本Activity中获取当前Activity中控件的height: Button button ...

  8. android 状态栏、标题栏、屏幕高度

    1.获取状态栏高度: decorView是window中的最顶层view,可以从window中获取到decorView,然后decorView有个getWindowVisibleDisplayFram ...

  9. Android开发之有效获取状态栏(StatusBar)高度

    获取状态栏高度 一.传统方式:有时获取为0,解决方法看  二 1 2 3 4 代码 Rect frame = new Rect(); getWindow().getDecorView().getWin ...

随机推荐

  1. Android开发遇到手机无法弹出Toast

    今天遇到了一个很奇怪的问题,一个很简单的程序,就是点击按钮弹出一个Toast,但在手机上运行起来,却没有正常弹出Toast 第一反应就是看看是否调用了show方法,很显然,并不是这个低级问题,为了确定 ...

  2. Unity 3D Framework Designing(3)——构建View和ViewModel的生命周期

    > 对于一个View而言,本质上是一个MonoBehaviour.它本身就具备生命周期这个概念,比如,Awake,Start,Update,OnDestory等.这些是非常好的方法,可以让开发者 ...

  3. 【C++】智能指针详解(一):智能指针的引入

    智能指针是C++中一种利用RAII机制(后面解释),通过对象来管理指针的一种方式. 在C++中,动态开辟的内存需要我们自己去维护,在出函数作用域或程序异常退出之前,我们必须手动释放掉它,否则的话就会引 ...

  4. 前端总结·基础篇·JS(四)异步请求及跨域方案

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

  5. Oracle ASM数据库故障数据恢复过程

    一.故障描述 ASM磁盘组掉线 ,ASM实例不能mount.ASM磁盘组有4个500G的磁盘组成,数据库和ASM软件为10.2.0.1,急需恢复oracle数据库.二.故障分析   分析组成ASM磁盘 ...

  6. 大数据测试之hadoop集群配置和测试

    大数据测试之hadoop集群配置和测试   一.准备(所有节点都需要做):系统:Ubuntu12.04java版本:JDK1.7SSH(ubuntu自带)三台在同一ip段的机器,设置为静态IP机器分配 ...

  7. word-wrap: break-word;与word-break: break-all;文本自动换行

    word-break:break-all和word-wrap:break-word都是能使其容器如DIV的内容自动换行它们的区别就在于:1,word-break:break-all 例如div宽200 ...

  8. Android 开发之错误整理 [2014-04-28 09:22:28 - XXXX] Unable to resolve target 'android-18'

    在开发的时候难免会导入项目,那么怎么经常会遇到这个错误: [2014-04-28 09:22:28 - XXXX] Unable to resolve target 'android-18' targ ...

  9. Maven工程webinfo下面的JSP页面无法加载.js、.css文件的解决方案

    --下面是我的工程路径 --我jsp的写法 -----启动工程,访问js文件的路径是这样的, href="http://localhost:8080/activiti/css/public. ...

  10. linux环境下 mysql数据库忘记密码 处理办法UPDATE user SET Password = password ( 'new-password' ) WHERE User = 'root' ;

    整个修改过程大概3-10分钟(看个人操作),这个时间内mysql出于不需要密码就能登陆的状态,请设法保证系统安全 不罗嗦直接上步骤 1.vi /etc/my.cnf 在[mysqld]下,添加一句:s ...