View的getWidth()和getMeasuredWidth()有什么区别吗?

View的高宽是由View本身和Parent容器共同决定的。
getMeasuredWidth()getWidth()分别对应于视图绘制的measure和layout阶段。getMeasuredWidth()获取的是View原始的大小,也就是这个View在XML文件中配置或者是代码中设置的大小。getWidth()获取的是这个View最终显示的大小,这个大小有可能等于原始的大小,也有可能不相等。比如说,在父布局的onLayout()方法或者该View的onDraw()方法里调用measure(0, 0),二者的结果可能会不同(measure中的参数可以自己定义)。

getWidth()

/*** Return the width of the your view.* @return The width of your view, in pixels.*/@ViewDebug.ExportedProperty(category = "layout")public final int getWidth() {return mRight - mLeft;}

从源码上看,getWidth()是根据mRightmLeft之间的差值计算出来的,需要在布局之后才能确定它们的坐标,也就是说布局后在onLayout()方法里才能调用getWidth()来获取。因此,getWidth()获取的宽度是在View设定好布局后整个View的宽度。

getMeasuredWidth()

/*** Like {@link #getMeasuredWidthAndState()}, but only returns the* raw width component (that is the result is masked by* {@link #MEASURED_SIZE_MASK}).** @return The raw measured width of this view.*/public final int getMeasuredWidth() {return mMeasuredWidth & MEASURED_SIZE_MASK;}

从源码上看,getMeasuredWidth()获取的是mMeasuredWidth的这个值。这个值是一个8位的十六进制的数字,高两位表示的是这个measure阶段的Mode的值,具体可以查看MeasureSpec的原理。这里mMeasuredWidth & MEASURED_SIZE_MASK表示的是测量阶段结束之后,View真实的值。而且这个值会在调用了setMeasuredDimensionRaw()函数之后会被设置。所以getMeasuredWidth()的值是measure阶段结束之后得到的View的原始的值。

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));}protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {boolean optical = isLayoutModeOptical(this);if (optical != isLayoutModeOptical(mParent)) {Insets insets = getOpticalInsets();int opticalWidth  = insets.left + insets.right;int opticalHeight = insets.top  + insets.bottom;measuredWidth  += optical ? opticalWidth  : -opticalWidth;measuredHeight += optical ? opticalHeight : -opticalHeight;}setMeasuredDimensionRaw(measuredWidth, measuredHeight);}private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {mMeasuredWidth = measuredWidth;mMeasuredHeight = measuredHeight;mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;}

总结一下,getMeasuredWidth是measure阶段获得的View的原始宽度,getWidth是layout阶段完成后,其在父容器中所占的最终宽度

如何在onCreate中拿到View的宽度和高度?

在onCreate()中获取View的高宽有三种方法:

  1. View.post(runnable)
view.post(new Runnable() {@Overridepublic void run() {int width = view.getWidth();int measuredWidth = view.getMeasuredWidth();Log.i(TAG, "width: " + width);Log.i(TAG, "measuredWidth: " + measuredWidth);}});

利用Handler通信机制,发送一个Runnable到MessageQueue中,当View布局处理完成时,自动发送消息,通知UI进程。借此机制,巧妙获取View的高宽属性,代码简洁,相比ViewTreeObserver监听处理,还不需要手动移除观察者监听事件。

  1. ViewTreeObserver.addOnGlobalLayoutListener()

监听View的onLayout()绘制过程,一旦layout触发变化,立即回调onLayoutChange方法。
注意,使用完也要主要调用removeOnGlobalListener()方法移除监听事件。避免后续每一次发生全局View变化均触发该事件,影响性能。

ViewTreeObserver vto = view.getViewTreeObserver();vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {view.getViewTreeObserver().removeGlobalOnLayoutListener(this);Log.i(TAG, "width: " + view.getWidth());Log.i(TAG, "height: " + view.getHeight());}});
  1. View.measure(int widthMeasureSpec, int heightMeasureSpec)

除了在onCreate()中获得View的高宽,还可以在Activity的onWindowFocusChanged() 方法中获得高宽。

getMeasuredWidth和getWidth的区别相关推荐

  1. View 绘制体系知识梳理(7) getMeasuredWidth 和 getWidth 的区别

    前言 前几天被问到了getMeasuredWidth和getWidth之间的区别,因此回来看了一下源码,又顺便复习了一遍measure/layout/draw的过程,有兴趣的同学可以看前面的几篇文章 ...

  2. 自定义View:测量measure,布局layout,绘制draw

    1. 什么是View 在Android的官方文档中是这样描述的:表示了用户界面的基本构建模块.一个View占用了屏幕上的一个矩形区域并且负责界面绘制和事件处理. 手机屏幕上所有看得见摸得着的都是Vie ...

  3. android layout过程分析,Andriod 从 0 开始自定义控件之 View 的 layout 过程 (八)

    前言 在上一篇文章了,我们学习了 View 三大流程之一的 measure 过程,当 measure 过程完成后,View 的大小就测量好了.接下来就到了 layout 的过程了,layout 的过程 ...

  4. Android 面试系列(一)Android 基础

    文章目录 序言 四大组件 Activity Activity 生命周期 onStart() 与 onResume() 区别? Activity 启动模式 launchMode 使用 Intent 标记 ...

  5. Android 精华 - 收藏全集 -

    Android - 收藏集 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发 ...

  6. Android学习笔记三

    大神博客(必看)http://blog.csdn.net/huachao1001/article/list/1 1.Android校招笔记 http://huachao1001.github.io/i ...

  7. 自定义view - 收藏集 - 掘金

    Android 从 0 开始自定义控件之 View 的 draw 过程 (九) - Android - 掘金 转载请标明出处: http://blog.csdn.net/airsaid/... 本文出 ...

  8. Android开发 - 收藏集

    Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity的显示之ViewRootImpl初探 Activity的显示之Window和View ...

  9. 掘金 Android 文章精选合集

    掘金官方 2017.07.10 16:42* 字数 175276 阅读 46638 评论 12 喜欢 653 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有 ...

最新文章

  1. getURLParameters - 网址参数
  2. 阿里招“AI鉴黄体验官”:日薪1000!网友:钱不钱无所谓,净化互联网人人有责!...
  3. python 字符串 数组 判断,Python的字符串的数组指数
  4. 关于“服务器提交了协议冲突. Section=ResponseStatusLine问题
  5. ue4模型为啥这么亮_坐好了,仔细听,资深建模师介绍UE4视口中的可视化模式(一)...
  6. 2021年已经过去了4天,创业者、负债累累而希望通过再创业实现东山再起者,你们准备的怎么样了?
  7. java栈匹配括号_使用到栈结构的一个表达式括号匹配检查类
  8. 甘特图制作_甘特图是用什么软件制作?
  9. 朴素贝叶斯,拉普拉斯平滑
  10. Pygame实战:下五子棋吗?信不信我让你几步你也赢不了?
  11. 计算机毕业设计(附源码)python校园疫情防控管理软件
  12. Java面试宝典2013版
  13. java ice c_ZeroC ICE之旅------java
  14. 结束语-放弃完美主义,执行力就是限时限量认真完成
  15. 神经网络与深度学习 作业3:分别使用numpy和pytorch实现FNN例题
  16. Tiny4412使用汇编点亮LED,实现流水灯效果
  17. 一条通往合格动力电池热管理仿真和设计工程师之路
  18. c语言程序设计书实验电子版,C语言程序设计实验指导书(学生用书)-修订版.pdf
  19. 网站导航、收录多个领域的网站、工具,持续更新中。
  20. java飞秋源码,feiQiu 实现飞秋系统,和qq 类似,能够 客户端和服务器端 Java Develop 259万源代码下载- www.pudn.com...

热门文章

  1. linux c显示日期,Linux C判断日期格式是否合法
  2. Content-Disposition 响应头,设置文件在浏览器打开还是下载
  3. Manjaro使用笔记-使用中国源的方法
  4. filter-mutate过滤插件
  5. iOS开发 - App程序启动原理
  6. 洛谷P1061 Jam的计数法
  7. 51nod 1040最大公约数和(欧拉函数)
  8. [webview] 放大缩小的问题
  9. 如何改变XCode的默认设置
  10. U3D-FSM有限状态机的简单设计