脚本宝典收集整理的这篇文章主要介绍了[Android] 如何计算View的Size,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
** 注:本文参考链接How Android caculates view size
本文例子如下所示:
<LinearLayout
andROId:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:layout_width="match_parent"
android:layout_height="20dp" />
</LinearLayout>
过程@H_512_67@
计算view大小的过程可以分为以下几个步骤:
- 确定view想要的size(LayoutParams)
- 确定parent view的情况(MeasureSpec)
- 在Parent view的限制下,根据view的LayoutParams,确定view的大小
参数
LayoutParams
LayoutParams用于view表示想要的size的模式。有以下三种:
- FILL_PARENT / MATCH_PARENT (-1)
view的size和parent view的size一样大
- WRAP_CONTENT(-2)
view的size仅包裹其内容即可
- 指定的值(>0)
view的size为指定的size大小
MeasureSpec
MeasureSpec表示当前view的“约束”(在onMeasure中传入)。约束含模式mode和数值size,当前view根据mode来决定如何看待其中的size。
mode
mode有三种,如下所示:
- UNSPECIFIED
对当前view的size没有约束
- EXACTLY
当前view的bounds(可以理解成“可以使用的范围”)为确定的size,也可以理解成parent view希望当前view(有强制的意味)使用给定的size
- AT_MOST
当前view的大小不可超过指定的size
可以利用MeasureSpec的getMode取出具体值.
size
size为8个byte的int值,mode放在前2个bit中。这里可以利用MeasureSpec的getSize取出size的具体值。
onMeasure过程
view通过onMeasure确定自己的大小。确定自己的大小时,需要的东西有:
- 约束MeasureSpec
- 自己的LayoutParams
- 如果有child view,那么需要获取child view的大小
最终确定当前view的size分别为:
- measureWidth
- measureHeight
single view
以前面例子中的TextView为例,其onMeasure中传入的MeasureSpec为:
- Width
mode:EXACTLY size:parentContentWidth(LinearLayout的宽-padding)
- Height
mode:AT_MOST size:parentContentHeight(LinearLayout的高-padding)
注:这里先不解释为什么MeasureSpec是这样的。
TextView的LayoutParams为:
- Width
MATCH_PARENT
- Height
WRAP_CONTENT
然后TextView根据约束和LayoutParams确定自己的大小,包括但不限于以下过程:
- 设置宽度为parentContentWidth,考虑margin确定字符可用范围
- 根据字符高度和字体设置(根据是否超过parentContentWidth确定是否换行)等计算字符所占的高度(没有限制)。
- 设置measureWidth和measureHeight
ViewGroup
以前面例子中的LinearLayout为例,假设该LinearLayout为Activity中的root layout其onMeasure中传入的MeasureSpec为:
- Width
mode:EXACTLY size:parentContentWidth(LinearLayout的parent view的宽-padding)
- Height
mode:AT_MOST size:parentContentHeight(LinearLayout的parent view的高-padding)
RelativeLayout的LayoutParams为:
- Width
MATCH_PARENT
- Height
WRAP_CONTENT
- Orientation
vertical
然后LinearLayout根据约束和LayoutParams确定自己的大小,包括但不限于以下过程:
- 确定child view的排列方式
- 确定TextView的size
- 确定ImageView的size
- 根据自身的设置,设置measureWidth和measureHeight
要确定child view的size,就要调用child view的onMeasure,传入合适的MeasureSpec,表明parent view对child的约束。
根据parent view的不同module和child view的不同LayoutParams,有如下规则:
-
当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.
-
当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.
-
当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为例:
- LinearLayout的width mode为EXACTLY,TextView的width layout param为MATCH_PARENT
- LinearLayout的height mode为AT_MOST,TextView的height layout param为WRAP_CONTENT
所以TextView的onMeasure会被传入:
- Width
mode:EXACTLY size:parentContentWidth(LinearLayout的宽-padding)
- Height
mode:AT_MOST size:parentContentHeight(LinearLayout的高-padding)
TextView可以根据上述约束计算自己的大小。ImageView同理。最后LinearLayout根据ImageView和TextView的大小计算自己的大小。注意这里没有weight的设置,所以onMeasure只运行一次。
如上述有错,请留言告知。
以上是脚本宝典为你收集整理的[Android] 如何计算View的Size全部内容,希望文章能够帮你解决[Android] 如何计算View的Size所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。