Android 在实际开发过程中,我们可能经常要获取View的宽和高,那么如何来正确获取一个View的宽和高呢。

View提供了getWidth(),getHeight(),getMeasureWidth(),getMeasureHeight()
方法来获取View的宽和高,getWidth(),getHeight()获取的是View最终显示的宽和高
也即实际宽和高,而getMeasureWidth(),getMeasureHeight()获取的是View测量后的宽和高,一般情况下getMeasureWidth(),getMeasureHeight()和getWidth(),getHeight()的值是一样的,但不是一定一样。
那么在Activity中是不是只要调用view的上面方法就能正确的获取到View的宽和高,你会发现,在Activity的onCreate(),onStart(),onResume()生命周期中调用上述方法获取到
View的宽和高都是0。这是因为在Activity上面的生命周期函数中,View还没有测量,和布局好,任何一个View的绘制都要经过onMeasure()测量,onLayout()布局,onDraw()绘制 这三个过程,而getWidth(),getHeight()获取的是View的实际宽和高,必须要在onLayout之后才能获取到View的宽和高,getMeasureWidth()和getMeasureHeight()必须要在onMeasure()之后才能获取到View的测量的宽和高。

下面来看看到底如何正确的获取到View的宽和高

(1)在Activity的onWindowFocusChanged(boolean hasFocus)方法中通过 getWidth(),getHeight();getMeasureWidth(),getMeasureHeight()可以获取到View的宽和高。

onWindowFocusChanged(boolean hasFocus)是在Activity当前Window获取焦点,失去焦点时,会回调这个方法,当Activity的获取到焦点时,其中的View是已经完成了onMeasure()测量和onLayout()布局,所以可以正确获取到View的宽和高。
但是要注意的是,只要Activity的当前Window获取焦点或者失去焦点都会回调该方法,
所以要注意的是判断一下只在第一次获取到焦点时获取View的宽和高

  @Overridepublic void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus);if(mFirstFocus){mFirstFocsu=false;Log.e(TAG, "onWindowFocusChanged: " + view.getWidth() + "," + view.getHeight());Log.e(TAG, "onWindowFocusChanged: " + view.getMeasuredWidth() + "," + view.getMeasuredHeight());}}

(2)View 的 post(Runnable action) 方法里可以通过上述方法获取到View的宽和高。
View的post(Runnable action) 方法是添加一个操作到队列末尾,当等到View attachToWindow时调用。,当View attachToWindow,已经进行了onMeasure()和onLayout()所以可以获取到宽高。

view.post(new Runnable(){//获取View的宽和高操作Log.e(TAG, "onCreate: "+view.getWidth()+","+view.getHeight());Log.e(TAG, "onCreate: "+view.getMeasuredWidth()+","+view.getMeasuredHeight());});

(3)使用 View的 measure(int widthMeasureSpec, int heightMeasureSpec) 测量 View
的宽高后,获取View测量的宽高。

测量后就可以调用getMeasureWidth()和getMeasureHeight()来获取ViewC测量的宽和高。

view.measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED);
Log.e(TAG, "onCreate: "+view.getMeasuredWidth()+","+view.getMeasuredHeight());

(4)ViewTreeObserver. OnPreDrawListener
给View添加onPreDrawListener监听,在View将要绘制时,通过上述方法获取View的宽和高,因为View将要绘制时,已经经过了onMeasure(),onLayout(),所以可以获取到
View的宽和高。但是onPreDrawListener可能会被回调多次,所以注意移除。

view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {@Overridepublic boolean onPreDraw() {Log.e(TAG, "onCreate: "+view.getWidth()+","+view.getHeight());Log.e(TAG, "onCreate: "+view.getMeasuredWidth()+","+view.getMeasuredHeight());//移除监听view.getViewTreeObserver().removeOnPreDrawListener(this);return false;}});

(5)ViewTreeObserver. OnDrawListener
给View添加OnDrawListener监听,在View绘制时,通过上述方法获取View的宽和高,
OnPreDrawListener 和 OnPreDrawListener使用一样,注意移除
(6)ViewTreeObserver. OnGlobalLyoutListener 在View的布局和可见性发生改变时
会回调。 使用和OnPreDrawListener,OnDrawListener一样,也会回调多次,注意移除。

Android 正确获取View的宽和高相关推荐

  1. Android中获取屏幕的宽和高

    常用方法: Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.ge ...

  2. Android基础 获取屏幕的宽与高

    /*** 获取屏幕的宽度* @param context* @return*///方法一public static int getScreenWidth(Context context) {Displ ...

  3. Android 获得view的宽和高

    在oncreate()中利用view.getWidth()或是view.getHeiht()来获取view的宽和高,看似没有问题,其实他们去得值是0,并不是你想要的结果? 这是为什么呢? 在调用onc ...

  4. 面试官问我:View.post为什么能够获取View的宽高

    记得看文章三部曲,点赞,评论,转发. 微信搜索[程序员小安]关注还在移动开发领域苟活的大龄程序员,"面试系列"文章将在公众号同步发布. 1.前言 最近看到几个技术群里都在吐槽目前面 ...

  5. JAVA获取图片的宽、高和大小

    JAVA获取图片的宽.高.大小 如果是本地磁盘文件 File file = new File("C:\\Users\\root\\Desktop\\test.jpg");Buffe ...

  6. java获取网络图片的宽和高

    /*** 获取网络图片的宽和高* @param url* @return*/public static String getWidthAndHeight(String url) {try {Input ...

  7. 通过View.post()获取View的宽高

    在Android里,获取View宽高的时机是个老生常谈的话题了.众所周知,在Oncreate里直接调用View.getWidth或者View.getMeasuredWidth返回都是0.所以获取宽高时 ...

  8. android获取控件宽和高

    Android获取控件宽高 在项目中用到了测量控件的宽和高,这个在Activity的onCreate去使用控件的getHeight()和getWidth()方法去获取是会失败的,返回的都是0.这是由于 ...

  9. 当View为GONE状态时获取View的宽高

    首先要明白一点就是一般情况下,我们在Activity里面的onCreate里面获取View宽高,可以采用: (1)View布局完成的监听 button.getViewTreeObserver().ad ...

最新文章

  1. 平民架构的春天——UCloud数据方舟实战记
  2. 一套模块化数据中心培训资料
  3. ITK:设置默认的线程数
  4. IO多路复用 select、poll、epoll
  5. 提高ASP.net性能的十种方法
  6. CSS鼠标悬停隐藏展开简介特效
  7. access 图片存储的格式_Ceph对象存储RGW架构及安装实战
  8. java基础学习-(2)堆和栈
  9. 撸一串经典的detection tracking
  10. matplotlib显示图中标签
  11. mfc 如何将cstring转byte_如何将PDF转成JPG?PDF转图片的技巧
  12. 多普达D700手机利用USB电缆与电脑连接上网方法
  13. 【amp;#9733;】SPF(Dijkstra)算法完美教程
  14. sql server2008如何修改mac地址_QCC304x/QCC514x:修改蓝牙MAC地址及名称
  15. 数据库锁机制 很详细的教程,易懂
  16. 拨开历史的迷雾从篡夺者战争到五王之战的政经原因
  17. Android 获取地理位置的经度和纬度
  18. 【理解】Beta贝塔分布
  19. 润迈德医疗上市首日跌15%:年亏6.3亿 平安资本是股东
  20. wincap问题之一(丢包)

热门文章

  1. Unicode 发布新版本,「biáng biáng 面」马上可以打出来了!
  2. 机器人出卢安娜飓风_LOL丨司马老贼用“血的教训”告诉你:这些英雄真不适合出飓风!...
  3. 计算机是人类的好伴侣 作文,书我的好伴侣作文
  4. linux安全设置:限制su、sudo切换root用户权限设置,su\sudo使用,SSH远程连接密钥登录
  5. Android隐藏底部虚拟导航栏及系统状态栏终极方案
  6. 读课文|读笔记|读小说|甚至读漫画|教你如何让书开口说话
  7. 基础会计-笔记 v1.0
  8. 华为陈帮华:数字化转型的阿基米德技术支点
  9. Activiti工作流引擎基础入门【收藏可做笔记系列】
  10. 佛学的108条做人道理