转载请标明出处:1片枫叶的专栏

上1个github小项目中我们介绍了避免按钮重复点击的小框架,其实现的核心逻辑是重写OnClickListener的onClick方法,添加避免重复点击的逻辑,即为第2次点击与第1次点击的时间间隔添加阙值,若第2次点击的时间间隔与第1次点击的时间间隔小于阙值,则此次点击无效,再次基础上我们又封装了点击组件验证网络Listener,点击组件验证是不是登录Listener等,具体可参考: github项目解析(7)–>避免按钮重复点击

本文中我将介绍1下android中Activity启动时获得组件宽高的3种方式。我们知道,有时候我们需要在Activity启动的时候获得某1组件的宽或是高用于动态的更改UI布局文件,但是这时候候我们直接通过getWidth和getHeight方法获得是有问题的。为何这么说呢?这里我们可以下1个测试的例子来验证1下:

问题:

在Activity的启动流程中通过getWidht和getHeight方法获得组件的宽度和高度

/**

* 在onCreate方法中调用,用于获得TextView的宽度和高度

*/

private void getTextHeightAndWidth() {

// 我们定义的用于获得宽度和高度的组件

titleText = (TextView) findViewById(R.id.text_title);

int height = titleText.getHeight();

int width = titleText.getWidth();

Log.i(TAG, "height:" + height + " " + "width:" + width);

}

这段代码看似是正常没有问题的,但是我们将调用的代码写在onCreate方法的时候,履行这段代码以后,打印的结果:

06-26 20:12:15.356 19453-19453/uuch.com.android_viewheight I/MainActivity: height:0 width:0

咦?为何打印的height和width都是0呢?我们在履行1遍呢?结果还是1样的,两个变量都是0,难道这段代码不能再onCreate方法中调用,那末我们试试在onResume方法中调用呢?

只能说然并卵,打印的结果仍然是:

06-26 20:52:13.986 19453-19453/uuch.com.android_viewheight I/MainActivity: height:0 width:0

好吧,问题已出来了,看模样我们是不能再onCreate方法或是onResume方法中调用该方法获得组件的宽高的,但是这是为何呢?平时我们都是通过这个方法来获得组件的宽高的,并且也没问题啊,比如我们将这个方法的调用逻辑写在按钮的点击事件以内呢?我们再来试试。

/**

* 这里的button1是我们定义的Button组件,并且我们重写了Button的点击事件,在其中调用了获得组件宽高的方法

*/

button1 = (Button) findViewById(R.id.button1);

button1.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

getTextHeightAndWidth();

}

});

这样敲完代码以后,我们履行这段代码,界面入下图所示:

那末我们的打印结果呢?

06-26 20:57:08.188 22648-22648/uuch.com.android_viewheight I/MainActivity: height:57 width:225

恩?这时候候我们发现其打印出了组件的宽和高,那末为何我们在Activity的onCreate、onResume方法中打印的时候,输出的组件宽高都是为0呢?

缘由:

其实看过我之前写过的

android源码解析之(104)–>Activity启动流程

android源码解析(107)–>Activity布局加载流程

android源码解析(108)–>Activity布局绘制流程

的同学应当对Activity的启动流程和其布局加载绘制流程不陌生,Activity的启动流程和Activity的布局文件加载绘制流程,其实没有相干的关系的,其实两个异步的加载流程,这样我们在Activity的onCreate和onResume方法调用textView.getHeight或是textView.getWidth方法的时候,其组件并没有履行完绘制流程,因此此时获得到的组件的宽高都是默许的0,也就是没法获得组件的宽和高。

但是当我们将获得组件宽高的方法卸载按钮的点击事件的时候,由于此时按钮已显示出来了,所以证明布局文件已加载绘制完成,这时候候点击组件履行组件的获得宽高方法,就可以正常的获得到组件的宽和高了。

这也就是为何我们在onCreate和onResume方法中调用获得组件宽高都是0,而在按钮的点击事件中获得的时候正常的缘由了。

其他解决方案:

那末如果我们想在Activity的onCreate方法或是onReusme方法获得组件的宽高怎样办呢?这里提供了以下的3种方式:

重写Activity的onWindowFocusChanged方法

/**

* 重写Acitivty的onWindowFocusChanged方法

*/

@Override

public void onWindowFocusChanged(boolean hasFocus) {

super.onWindowFocusChanged(hasFocus);

/**

* 当hasFocus为true的时候,说明Activity的Window对象已获得焦点,进而Activity界面已加载绘制完成

*/

if (hasFocus) {

int widht = titleText.getWidth();

int height = titleText.getHeight();

Log.i(TAG, "onWindowFocusChanged width:" + widht + " "

+ " height:" + height;

}

}

说明:

这样重写onWindowFocusChanged方法,当获得焦点的时候我们就能够通过getWidth和getHeight方法得到组件的宽和高了。但是这时候候这个方法的逻辑可能会履行屡次,也就是说只要我们的Activity的window对象获得了焦点就会履行该语句,所以我们需要做1些逻辑判断,让它在我们需要打印获得组件宽高的时候在履行。

为组件添加OnGlobalLayoutListener事件监听

/**

* 为Activity的布局文件添加OnGlobalLayoutListener事件监听,当回调到onGlobalLayout方法的时候我们通过getMeasureHeight和getMeasuredWidth方法可以获得到组件的宽和高

*/

private void initOnLayoutListener() {

final ViewTreeObserver viewTreeObserver = this.getWindow().getDecorView().getViewTreeObserver();

viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

Log.i(TAG, "开始履行onGlobalLayout().........");

int height = titleText.getMeasuredHeight();

int width = titleText.getMeasuredWidth();

Log.i(TAG, "height:" + height + " width:" + width);

}

});

}

说明:

需要说明的是这里的onGlobalLayout方法会在Activity的组件履行完onLayout方法以后履行,这里的onLayout方法主要用于计算组件的宽高操作,具体可参考:android源码解析(108)–>Activity布局绘制流程,这样当我们计算完组件的宽高以后再履行获得组件的宽高操作,自然能够获得到组件的宽度和高度。

为组件添加OnPreDrawListener事件监听

/**

* 初始化viewTreeObserver事件监听,重写OnPreDrawListener获得组件高度

*/

private void initOnPreDrawListener() {

final ViewTreeObserver viewTreeObserver = this.getWindow().getDecorView().getViewTreeObserver();

viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

@Override

public boolean onPreDraw() {

Log.i(TAG, "开始履行onPreDraw().........");

int height = titleText.getMeasuredHeight();

int width = titleText.getMeasuredWidth();

Log.i(TAG, "height:" + height + " width:" + width);

return true;

}

});

}

说明:

需要说明的是这里的onPreDraw方法会在Activity的组件履行onDraw方法之前履行,熟习我们Activity组件加载绘制流程的同学应当知道,这里的onDraw方法主要用于履行真实的绘制组件操作,而这时候候我们已计算出来了组件的位置,宽高等操作,这样以后再履行获得组件的宽高操作,自然能够获得到组件的宽度和高度。

其他说明:

需要说明的是如果对Acitivty的布局加载绘制流程比较了解的同学应当知道,界面的显示进程经过了:丈量位置,丈量大小,绘制,3个操作流程。而我们获得组件的宽高就是获得组件的大小,所以我们获得的代码必须要在组件履行完丈量大小以后,而不管是我们添加的onWindowFocusChanged方法,onPreDrawListener监听,已onGlobalLayoutListener监听其实都是在组件完成了丈量大小以后履行了,因此这时候候我们能够正确的获得到组件的宽和高。

总结:

该类库主要是介绍了3种我们在Activity的启动进程中获得组件宽高的方式;

通太重写onWidnowFocusChanged方法获得组件宽高的方式,可能会回调几次,这点需要我们注意;

项目保存地址:android-viewheight,欢迎star和follow

另外对github项目,开源项目解析感兴趣的同学可以参考我的:

github项目解析(1)–>上传android项目至github

github项目解析(2)–>将Android项目发布至JCenter代码库

github项目解析(3)–>android内存泄漏监测之leakcanary

github项目解析(4)–>动态更改TextView的字体大小

github项目解析(5)–>android日志框架

github项目解析(6)–>自定义实现ButterKnife框架

github项目解析(7)–>避免按钮重复点击

html获取此次点击的id,github项目解析(八)--Activity启动过程中获取组件宽高的三种方式...相关推荐

  1. Github项目解析(九)--实现Activity跳转动画的五种方式

    2019独角兽企业重金招聘Python工程师标准>>> 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请标明出处:一片枫叶的专栏 上一篇文章中我们讲解了在Activity ...

  2. Github项目解析系列

    转载请标明出处:一片枫叶的专栏 Github项目解析系列主要解析的是平时开发过程中遇到的小项目小例子,自己总结的一些研发技巧与实践,以及一些Github中流行的项目等.基本上blog中所涉及到的项目都 ...

  3. 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 反射获取 IActivityManager 对象 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  4. 【REACT NATIVE 系列教程之十三】利用LISTVIEW与TEXTINPUT制作聊天/对话框获取组件实例常用的两种方式...

    本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/react-native/2346.html ...

  5. vue前端常用的三种方式模拟获取数据

    前端的三种方式模拟获取数据 1⃣️.mockjs插件获取: 1.首先我们先进行安装mockjs,进入项目在终端输入:npm install mockjs --save 2.我们可以在src目录下新建m ...

  6. android获取自定义属性,android 自定义控件中获取属性的三种方式(转)

    第一种方法,直接设置属性值,通过attrs.getAttributeResourceValue拿到这个属性值. (1)在xml文件中设置属性值 android:layout_width="f ...

  7. java获取反射机制的三种方式

    更多免费教学文章请关注这里 java 获取反射常使用的三种方式: 1.通过new对象实现反射机制 2.通过路径实现反射机制 3.通过类名实现反射机制 通过Object类的getClass方法来获取 使 ...

  8. Github项目解析(五)--Android日志框架

    转载请标明出处:一片枫叶的专栏 本文主要讲解的是自己实现一个简单的Android日志框架,可以在Android studio控制台中输入日志信息,其简单的使用方式: L.v("...&quo ...

  9. Spring Boot当中获取request的三种方式

    本篇博客主要记录request相关知识,也是开发当中经常遇到的,感兴趣的跟小编一起学习吧! 目录 一.请求过程 二.获取request的三种方式 2.1.可以封装为静态方法 2.2.controlle ...

最新文章

  1. 使用MaxCompute Java SDK 执行任务卡住了,怎么办?
  2. 产品开发专业认证_食品招生季食品科学与工程专业介绍
  3. mysql ---- innodb-2-索引
  4. 探讨视频云与边缘云平台的竞争力 ——基于Serverless的端边云一体化媒体网络...
  5. 服务器物理结构,物理 I/O 体系结构
  6. Docker容器的自动化监控实现
  7. java seteditable,Java TextField.setEditable方法代碼示例
  8. hadoop 权限错误 Permission denied: user=root, access=WRITE, inode=“/“:hdfs:super
  9. SSM-SpringMVC-15:SpringMVC中小论注解式开发之通配符篇
  10. 大数据实战:如何实时采集上亿级别数据?
  11. Oracle(plsql)数据导入导出
  12. [微软中国]秋季校园招聘开启了(可内推)
  13. 关于STM32H7的串口DMA的使用
  14. 因为洋红色被告垄断,德国电信心塞
  15. Confluence 文档协作平台安装部署笔记
  16. ClickHouse Kafka引擎表 Application maximum poll interval ... leaving group
  17. 杭州建筑工程师职称评审条件
  18. 四分位数的应用——基于收入实例的箱体图与离群值规则
  19. 网络连接状态断开服务器无响应,已断开(服务器无响应),路由器连不上网什么原因...
  20. buuctf-had a bad day

热门文章

  1. python文本字符串比对_python-模糊字符串比较
  2. MySQL Workbench运行脚本
  3. Android数据存储之sharedpreferences与Content Provider
  4. 小甲鱼 OllyDbg 教程系列 (十一) : inline patch ( 内嵌补丁 )
  5. Spring Data JPA 从入门到精通~实际工作的应用场景
  6. 无法初始化链接服务器 (null) 的 OLE DB 访问接口 Microsoft.Jet.OLEDB.4.0 的数据源对象。
  7. java equals 判断空_Java 判断字符串是否为空的三种方法与性能分析
  8. redis配置mysql缓存_Redis做mysql的缓存服务器
  9. python中的set方法_Python中set与frozenset方法和区别详解
  10. PID控制器改进笔记之四:改进PID控制器之设定值响应