** 注:本文参考链接How Android caculates view size

本文例子如下所示:

        

过程

计算view大小的过程可以分为以下几个步骤:

  1. 确定view想要的size(LayoutParams)
  2. 确定parent view的情况(MeasureSpec)
  3. 在parent view的限制下,根据view的LayoutParams,确定view的大小

参数

LayoutParams

LayoutParams用于view表示想要的size的模式。有以下三种:

  1. FILL_PARENT / MATCH_PARENT (-1)
    view的size和parent view的size一样大
  2. WRAP_CONTENT(-2)
    view的size仅包裹其内容即可
  3. 指定的值(>0)
    view的size为指定的size大小

MeasureSpec

MeasureSpec表示当前view的“约束”(在onMeasure中传入)。约束含模式mode和数值size,当前view根据mode来决定如何看待其中的size。

mode

mode有三种,如下所示:

  1. UNSPECIFIED
    对当前view的size没有约束
  2. EXACTLY
    当前view的bounds(可以理解成“可以使用的范围”)为确定的size,也可以理解成parent view希望当前view(有强制的意味)使用给定的size
  3. AT_MOST
    当前view的大小不可超过指定的size

可以利用MeasureSpec的getMode取出具体值.

size

size为8个byte的int值,mode放在前2个bit中。这里可以利用MeasureSpec的getSize取出size的具体值。

onMeasure过程

view通过onMeasure确定自己的大小。确定自己的大小时,需要的东西有:

  1. 约束MeasureSpec
  2. 自己的LayoutParams
  3. 如果有child view,那么需要获取child view的大小

最终确定当前view的size分别为:

  1. measureWidth
  2. measureHeight

single view

以前面例子中的TextView为例,其onMeasure中传入的MeasureSpec为:

  1. Width
    mode:EXACTLY size:parentContentWidth(LinearLayout的宽-padding)
  2. Height
    mode:AT_MOST size:parentContentHeight(LinearLayout的高-padding)

注:这里先不解释为什么MeasureSpec是这样的。

TextView的LayoutParams为:

  1. Width
    MATCH_PARENT
  2. Height
    WRAP_CONTENT

然后TextView根据约束和LayoutParams确定自己的大小,包括但不限于以下过程:

  1. 设置宽度为parentContentWidth,考虑margin确定字符可用范围
  2. 根据字符高度和字体设置(根据是否超过parentContentWidth确定是否换行)等计算字符所占的高度(没有限制)。
  3. 设置measureWidth和measureHeight

ViewGroup

以前面例子中的LinearLayout为例,假设该LinearLayout为Activity中的root layout其onMeasure中传入的MeasureSpec为:

  1. Width
    mode:EXACTLY size:parentContentWidth(LinearLayout的parent view的宽-padding)
  2. Height
    mode:AT_MOST size:parentContentHeight(LinearLayout的parent view的高-padding)

RelativeLayout的LayoutParams为:

  1. Width
    MATCH_PARENT
  2. Height
    WRAP_CONTENT
  3. Orientation
    vertical

然后LinearLayout根据约束和LayoutParams确定自己的大小,包括但不限于以下过程:

  1. 确定child view的排列方式
  2. 确定TextView的size
  3. 确定ImageView的size
  4. 根据自身的设置,设置measureWidth和measureHeight

要确定child view的size,就要调用child view的onMeasure,传入合适的MeasureSpec,表明parent view对child的约束。

根据parent view的不同module和child view的不同LayoutParams,有如下规则:

  1. 当parent view的mode是EXACTLY时:

    child layout mode size
    exact size EXACTLY childSize Child wants a specific size.
    MATCH_PARENT EXACTLY parentContentSize Child wants to be parent's size.
    WRAP_CONTENT AT_MOST parentContentSize Child wants to determine its own size. It can not be bigger than parent.
  2. 当parent view的mode是AT_MOST时:

    child layout mode size
    exact size EXACTLY childSize Child wants a specific size
    MATCH_PARENT AT_MOST parentContentSize Child wants to be parent's size, but parent's size is not fixed. Constrain child to not be bigger than parent.
    WRAP_CONTENT AT_MOST parentContentSize Child wants to determine its own size, but it can not be bigger than parent.
  3. 当parent view的mode是UNSPECIFIED时:

    child layout mode size
    exact size EXACTLY childSize Child wants a specific size.
    MATCH_PARENT UNSPECIFIED can not decide yet Child wants to be parent's size. Child will decide its own size later.
    WRAP_CONTENT UNSPECIFIED can not decide yet Child wants to be its own size. Child will decide its own size later.

以例子中的TextView为例:

  1. LinearLayout的width mode为EXACTLY,TextView的width layout param为MATCH_PARENT
  2. LinearLayout的height mode为AT_MOST,TextView的height layout param为WRAP_CONTENT

所以TextView的onMeasure会被传入:

  1. Width
    mode:EXACTLY size:parentContentWidth(LinearLayout的宽-padding)
  2. Height
    mode:AT_MOST size:parentContentHeight(LinearLayout的高-padding)

TextView可以根据上述约束计算自己的大小。ImageView同理。最后LinearLayout根据ImageView和TextView的大小计算自己的大小。注意这里没有weight的设置,所以onMeasure只运行一次。

如上述有错,请留言告知。

更多相关文章

  1. Android下在onCreate方法中获取TextView的高度
  2. 【Android动画九章】-AlphaAnimation(渐变动画)
  3. Android获取窗口可视区域大小: getWindowVisibleDisplayFrame()
  4. TextView通过获得dimens.xml中定义的大小来动态设置字体大小
  5. Android中获取应用程序(包)的信息----PackageManager
  6. Context上下文的一些应用
  7. 【Android开发经验】兼容不同的屏幕大小(推荐,最官方的适应屏幕大
  8. android如何得到控件大小 OnGlobalLayoutListener
  9. android EditText 限制输入大小写,大写转小写

随机推荐

  1. Android基本组件介绍和生命周期
  2. AOSP ON MAKO(在NEXUS 4上刷ANDROID 4.4
  3. 下载Android(安卓)源码
  4. Android(安卓)常见问题之 android.conten
  5. 关于ANDROID下载与音乐播放
  6. 关于Android(安卓)traslateAnimation的坐
  7. ubuntu 10.10 编译Android2.2问题解决
  8. Android面试复习资料整理
  9. 定制个性化屏保
  10. 【Android】android的基本UI操作(2)以及小