浅谈屏幕适配之measure(下)——状态栏和标题栏相关操作_whuczh的博客-程序员秘密

技术标签: measure  屏幕适配  Android  状态栏和标题栏  

上一篇博文里给自己挖了一个坑,今天把这个坑埋了。之前说listView的高度=屏幕高度-标题栏和状态栏高度-titleBar高度-bottomTab高度,titleBar和bottomTab都是自己画的View,这个不难理解,那么标题栏和状态栏是哪一块呢?见下图:


标题栏和状态栏是android默认给出的两栏,每个应用新建的时候都会出现,如果要去掉这两栏,可以在Activity的setContentView之前写两行代码:

this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉
状态栏 

如果不去掉这两栏,而是要获取两栏的高度,以此来更好的进行屏幕的适配,一般网上给出的下述的方法:

public class MainActivity extends Activity {
	private int topHeight;
	private int titleHeight;
	private int statusHeight;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		getHeight();
	}

	private void getHeight() {
		// 状态栏+标题栏总高度
		topHeight = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
		// 状态栏高度
		Rect frame = new Rect();
		getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
		statusHeight = frame.top;
		//标题栏高度
		titleHeight = topHeight-statusHeight;
		Log.i("info", "topHeight>"+topHeight+" statusHeight>"+" titleHeight>"+titleHeight);
	}

}

我们来看看Log日志:


很明显,这种方法无法得到两栏的高度(上一篇中并非通过该方法得到两栏高度,后来修改时忘记改代码了)。那么我们该如何来获取高度呢?有好几种方法:

方法一:在Activity中复写onWindowFocusChanged()方法,将上述的几行代码写在onWindowFocusChanged()方法中:

@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		// TODO Auto-generated method stub
		super.onWindowFocusChanged(hasFocus);
		// 状态栏+标题栏总高度
		topHeight = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
		// 状态栏高度
		Rect frame = new Rect();
		getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
		statusHeight = frame.top;
		// 标题栏高度
		titleHeight = topHeight - statusHeight;
		Log.i("info", "topHeight>" + topHeight + " statusHeight>" + statusHeight + " titleHeight>" + titleHeight);
	}

ok,高度成功求出来了。但是onCreate()先于onWidowFocusChanged()执行,在onCreate的其他地方使用变量statusHeight或titleHeight时这两个值依旧为0,要使用这些值只能在onWidowFocusChanged()方法中添加方法,如上一篇中若要用此方法设置listview高度,代码如下:

private void setListViewHeight() {
		// 测量屏幕高度
		DisplayMetrics metric = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metric);
		totalHeight = metric.heightPixels;
		Log.i("info", "totalHeight>"+totalHeight);
		//底部高度
		bottomHeight = bottomTab.getLayoutParams().height;
		Log.i("info", "bottomHeight>"+bottomHeight);
		//顶部高度
		Log.i("info", "titleHeightWithoutMeasure>"+titleBar.getMeasuredHeight());
		titleBar.measure(0, 0);
		titleHeight = titleBar.getMeasuredHeight();
		Log.i("info", "titleHeightWithMeasure>"+titleHeight);
		//设置listview高度
		list.getLayoutParams().height = totalHeight-contentViewTop-titleHeight-bottomHeight;
		Log.i("info", "listHeight>"+list.getLayoutParams().height );
	}
@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		// TODO Auto-generated method stub
		super.onWindowFocusChanged(hasFocus);
		//状态栏高度
		Rect frame = new Rect();  
		getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);  
       		statusBarHeight = frame.top;  
       		// 获取标题栏+状态栏总高度
        	contentViewTop = getWindow()  
                .findViewById(Window.ID_ANDROID_CONTENT).getTop();  
        	// 标题栏高度  
       		titleBarHeight = contentViewTop - statusBarHeight;  
        	setListViewHeight();
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, data);
		list.setAdapter(adapter);
	}



方法一限制比较多,方法二可以直接写在onCreate中,代码如下:

// 状态栏高度
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusHeight = getResources().getDimensionPixelSize(resourceId);
}
Log.i("info", "statusHeight>" + statusHeight);

通过获取状态栏id的方式获取到状态栏的高度,很有意思的方法,有兴趣的同学可以去看看getIdentifier()和getDimensionPixelSize()这两个方法的源码

方法三也很有意思,我自己并没有去测试过。众所周知,Android的所有资源都会有惟一标识在R类中作为引用。我们也可以通过反射获取R类的实例域,代码如下:

public static int getStatusHeight(Context context) {
 //获取状态栏高度
    int statusHeight = -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());
        statusHeight = context.getResources().getDimensionPixelSize(height);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return statusHeight;
}




版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cai554112503/article/details/50083103

智能推荐

VS-watch窗口_weixin_30883311的博客-程序员秘密

在watch窗口中输入下面的内容: 1) @err,hr 显示API函数调用GetLastError的返回值,和解释 2) @eax,hr 显示eax寄存器的值,由于win的API的返回值放在eax中,所以这句话就是得到最近一个API 的返回值 3) p,***(数字) 数组指针扩展出来只有单个元素,而你又想看到全部数组元素,可以用这个技巧 4) VC调试观察窗口的格式化符号表格 ...

MooseFS 源码安装_S H W·的博客-程序员秘密

目录一 、前言1.Moosefs的介绍2.Moosefs的特征(1)层析结构(目录树)(2)存储文件属性(权限、访问和修改时间)(3)支持特殊文件(块设备,字符设备,管道)(4)符号链接,软硬链接(5)对文件系统访问可以通过IP地址或者密码进行访问限制(6)高可靠(数据的多个拷贝存储在不同的计算机上)(7)通过附加新的计算机或者硬盘可以实现容量的动态扩展(8)删除文件可以根据一个可配置的时间周期进行保留(9)不受访问和写入影响的文件连贯快照3.Moose.

Flask(5)- 请求钩子与上下文_君莫笑.的博客-程序员秘密

3.abort的使用目标:可以使用abort抛出http状态码异常文件: d03_abort.py作用: 抛出异常http状态码使用:# abort(http错误状态码) 4XX 5XXabort(404)4.异常捕获处理目标:可以使用errorhandler捕获异常文件: d04_errorhandler.py使用格式@app.errorh...

Apllo进阶课程25-Apollo自动驾驶架构介绍_apollo软件架构_世界围绕爱转动的博客-程序员秘密

Apollo自动驾驶架构介绍自动驾驶硬件架构:一般采用激光雷达作为主要感知传感器,同时结合摄像头、GPS/IMU、毫米波雷达、超声波雷达等,以NVIDIA Drive PX2 或 Xavier作为主要计算平台,在工业PC机上运行各种算法模块,通过线控技术控制车辆行驶。百度开源自动驾驶系统Apollo的架构图如下所示:Apollo自动驾驶平台的架构如下图所示。该架构是Apollo 在2017年7月5号发布的,主要包括四个部分:最底层的车辆平台,往上一层的传感器层,第三层的核心软件层以及最上层的云服务层

使用Filebeat配置Logstash_danpob13624的博客-程序员秘密

在配置ELK堆栈以分析Apache Tomcat日志的文章中,我们配置了Logstash从目录中提取数据,而在本文中,我们将配置Filebeat将数据推送到Logstash。 在配置之前,让我们简要介绍为什么需要Filebeat。 为什么要使用Filebeat? Filebeat有助于分散服务器的位置,从而从处理日志的位置生成日志,从而分担一台计算机的负载。 现在,让我们从配置开始,...

随便推点

PhpStorm编辑器删除空行_php代码格式化去除多余换行_丹婶的博客-程序员秘密

问题: 格式化代码文件,将多余的空行删除;解决: ctrl+R快捷键弹出替换框,搜索框:^\n将Regex打勾,Replace all 即可;

ASP.NET MVC构建RESTful服务时返回Unauthorized(401)状态_weixin_30732487的博客-程序员秘密

这两天在构建RESTful服务的客户端,本以为已经一马平川了,没有想到就在下班时遇到一个问题。我打算在服务器商把所处理的HTTP异常状态(400-599))状态一一返回给客户端组件,客户端收到各个状态码后根据号码及从服务器端返回的Description Content来抛出客户端的异常,结果在测试401时发现一个问题:在我的设想中,收到401,然后再去读取Response中的Status De...

如何在虚拟机里安装ubuntu系统_怎么在安装虚拟机ubuntu系统_qq_39526565的博客-程序员秘密

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Ma...

BZOJ 2154 Crash的数字表格 (莫比乌斯反演)_Sanzo00的博客-程序员秘密

Crash的数字表格今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple)。对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数。例如,LCM(6, 8) = 24。回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张NM的表格。每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j)。一个...

OpenResty学习——第五章 常用Lua开发库2-JSON库、编码转换、字符串处理_openresty 字符替换_Peter-OK的博客-程序员秘密

本文转自https://blog.csdn.net/jinnianshilongnian/article/details/84703641,好文要顶,感谢博主分享!JSON库在进行数据传输时JSON格式目前应用广泛,因此从Lua对象与JSON字符串之间相互转换是一个非常常见的功能;目前Lua也有几个JSON库,本人用过cjson、dkjson。其中cjson的语法严格(比如unico...

基于Linux的Hadoop伪分布式安装_linux安装hadoop伪分布_LeoATLiang的博客-程序员秘密

【大数据技术2】:基于Linux的Hadoop伪分布式安装。主要内容包含:创建用户、安装ssh、安装vim、安装JDK并配置环境变量、安装Hadoop、hadoop伪分布式配置以及启动HDFS伪分布式模式。

推荐文章

热门文章

相关标签