1、Activity界面的划分html
简单说明一下(上图Activity采用默认Style,状态栏和标题栏都会显示):最大的草绿色区域是屏幕界面,红色次大区域咱们称之为“应用程序界面区域”,最小紫色的区域咱们称之为“View绘制区域”;屏幕顶端、应用界面区以外的那部分显示手机电池网络运营商信息的为“状态栏”,应用区域顶端、View绘制区外部显示Activity名称的部分咱们称为“标题栏”。android
/** * 获取状态栏高度——方法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 * */ 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 * 应用区的顶端位置即状态栏的高度 * *注意*该方法不能在初始化的时候用 * */ Rect rectangle= new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(rectangle); //高度为rectangle.top-0仍为rectangle.top Log.e("-------", "状态栏-方法3:" + rectangle.top);
/** * 获取状态栏高度——方法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);
三、4这两种方法其实本质是同样,因此若是单单获取statusBar高度而不获取titleBar高度时也不推荐你们使用,理由同上方法3网络
//屏幕 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=0app
/** * 获取标题栏高度-方法1 * 标题栏高度 = View绘制区顶端位置 - 应用区顶端位置(也能够是状态栏高度,获取状态栏高度方法3中说过了) * */ int titleHeight1 = viewTop - outRect1.top; Log.e("--------", "标题栏高度-方法1:" + titleHeight1);
/** * 获取标题栏高度-方法2 * 标题栏高度 = 应用区高度 - View绘制区高度 * */ int titleHeight2 = outRect1.height() - outRect2.height(); Log.e("----------", "标题栏高度-方法2:" + titleHeight2);
*注意* spa
(1)无论你是否设置全屏模式,或是不显示标题栏,在使用获取状态栏高度方法1和获取状态栏高度方法2都会测量到状态栏的高度,理解原理就不难解释——系统资源属性是固定的、真实的,无论你是否隐瞒(隐藏或者显示),它都在那里;code
(2)可是若使用获取状态栏高度方法3和获取状态栏高度方法4,以及获取标题栏高度方法1和获取标题栏高度方法2,都是依赖于WMS,是在界面构建后根据View获取的,因此显示了就有高度,不显示天然没高度了。htm
下面是验证blog
先设置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);