getMeasuredWidth()和getWidth()

来源:互联网 发布:ios 小游戏源码 编辑:程序博客网 时间:2024/05/20 15:38

如何获取view的宽/高度?许多人都会用getWidth()或者getMeasuredWidth(),但是这两者有什么不一样呢?

View的绘制过程是measure->layout->draw。看下measure的代码:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));}public static int getDefaultSize(int size, int measureSpec) {    int result = size;    int specMode = MeasureSpec.getMode(measureSpec);    int specSize = MeasureSpec.getSize(measureSpec);    switch (specMode) {    case MeasureSpec.UNSPECIFIED:        result = size;        break;    case MeasureSpec.AT_MOST:    case MeasureSpec.EXACTLY:        result = specSize;        break;    }    return result;}

看下getDefaultSize函数,这个函数测量到的大小是根据父容器的measureSpec同时结合view本身的layoutparams来确定子元素的measureSpec。这时计算出的大小是getMeasuredWidth(),但是view最终的大小是在layout阶段确定的(用getWidth()读取),所以这里要加以区分,但是几乎所有情况下view的测量和最终大小是相等的。所以一个比较好的习惯是在onLayout函数中去获取view的大小。

如果在一个activity启动的时候,想要去获取某个view的宽高,是不可以在onCreate或者onResume等生命周期函数中去取,这是因为view的绘制和activity的生命周期是异步的,所以在这些生命周期函数中去绘制的话,会导致获取到的宽度为0。下面介绍几种方法来获取:

  1. 通过onWindowFocusChanged,这个方法的含义是:view已经初始化完毕了,宽高已经准备好了,这个时候去获取宽高是没问题的。当Activity的窗口获取焦点或失去焦点均会被调用,太频繁,这样不好。
  2. view.post(runnable):通过post可以将一个runnable投递到消息队列的尾部,然后等looper调用此runnable的时候,view也已经初始化好了。典型代码:
protected void onStart(){    super.onStart();    view.post(new Runnable(){         @Override         public void run(){             int width = view.getWidth();             int height = view.getHeight();         }     });}
  1. ViewTreeObserver:使用ViewTreeObserver的众多回调可以完成这个功能,比如使用onGlobalLayoutListener这个接口,当view树的状体发生改变或view树内部的view的可见性发生改变时,onGlobalLayout方法将被回调,因此这是一个获取view宽高很好的机会。需要注意的是,随着view树的变化,该回调将会被调用多次,获取宽高后需要remove该Listener。
void func(final View view){    view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {        @Override        public void onGlobalLayout() {            view.getViewTreeObserver().removeGlobalOnLayoutListener(this);            int width = view.getWidth();            int height = view.getHeight();        }    });}

MeasureSpec.UNSPECIFIED这种情况,一般用于系统内部的测量过程,getDefaultSize传入的specSize分别为getSuggestedMinimumWidth()和getSuggestedMinimumHeight()。

protected int getSuggestedMinimumWidth() {        return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());    }protected int getSuggestedMinimumHeight() {        return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());    }

如果这个view没有设置背景,那么返回的是mMinWidth或者mMinHeight,这两个值对应的是android:minWidth和android:minHeight,但是如果设置了background,就取background.getMinimumHeight和mMinHeight的大值。
那Drawable的getMinimumHeight()函数返回的是什么呢?

public int getMinimumHeight() {        final int intrinsicHeight = getIntrinsicHeight();        return intrinsicHeight > 0 ? intrinsicHeight : 0;}

可以看出getMinimumHeight返回的就是drawable的原始高度。如果是BitmapDrawable的话,返回bitmap的原始高度,如果是ShapeDrawable无原始高度,返回0。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老公出轨还不知道悔改妻子怎么办 离婚了前妻户口还在再婚怎么办 怀孕六个月内裤老是湿有异味怎么办 怀孕五个月内裤总是湿有异味怎么办 耳朵里面有个洞老是流水冒浓怎么办 宝宝拉粑粑有臭酸味怎么回事怎么办 老婆晚上回家内裤是湿的尿味怎么办 怀孕五个月下身痒内裤湿怎么办 哺乳期奶水太多经常弄湿衣服怎么办 麻料裙子一坐下就皱怎么办 不小心把答题卡弄皱了怎么办 嘴巴又干又黏又臭怎么办 不小心把红枣核吞了怎么办 小天才电话手表被偷了怎么办 18k金被火烧黑了怎么办 衣服掉色染到别的衣服上怎么办 夏天太阳太毒刚发芽的花种子怎么办 长斑了怎么办 喝玫瑰花茶能祛斑吗 烧纸火纸迷信纸利润太低怎么办 刚买的绣球花花有点蔫怎么办 ZF葡7正常佩戴动能太满怎么办 怀孕初期老婆婆做的菜不好吃怎么办 调节协议已签字不签收调解书怎么办 给晋中苗圃拉了树苗没拿上钱怎么办 多肉旁边长出好多小株怎么办 烤瓷牙制备时颌关系不够怎么办 对门放石头正对我家大门怎么办 合租的室友关门开门特别大声怎么办 三周岁的宝宝小阴唇再次粘连怎么办 小阴唇内侧长了毛囊炎很大疼怎么办 小阴唇上一个黄豆大的硬疙瘩怎么办 梦幻西游手游金币兑换上限了怎么办 手机放裤子口袋里易拔出怎么办 两个月宝宝拉肚子怎么办吃纯母乳 花王泡沫染停留时间太久怎么办 ps右下角的图层图标隐藏了怎么办 压缩包文件太大微信无法传送怎么办 一寸照片的尺寸在ps中怎么办 遇到尖酸刻薄爱数落人的领导怎么办 初中一年级的学生就不想读书怎么办 电脑上所有文件都变得很大怎么办