每日一问:详细说一下 MeasureSpec.UNSPECIFIED

详细说一下 MeasureSpec.UNSPECIFIED

前面的文章 我留下了一个疑惑,那就是到底为何 NestedScrollView 要把子 View 的测量模式强行设置为 MeasureSpec.UNSPECIFIED ,这不,在鸿洋的 "wanAndroid" 中,他再次提出了这样的问题:app

MesureSpec.UNSPECIFIEDthis

  1. 这个模式何时会遇到?
  2. 遇到后怎么处理?
  3. 有什么注意事项?

下面摘自用户「陈小缘啦啦啦」的回答,我以为回答的很是到位,特别在这里和你们分享一下。code

UNSPECIFID,就是未指定的意思,在这个模式下父控件不会干涉子 View 想要多大的尺寸。
那么,这个模式何时会onMeasure() 里遇到呢?实际上是取决于它的父容器。
就拿最经常使用的 RecyclerView 作例子,在 Item 进行 measure() 时,若是列表可滚动,而且 Item 的宽或高设置了 wrap_content 的话,那么接下来,itemView 的 onMeasure( )方法的测量模式就会变成 MeasureSpec.UNSPECIFIED
咱们不妨打开 RecyclerView 源码,会在 getChildMeasureSpec() 方法里看到这么一句注释:图片

MATCH_PARENT can't be applied since we can scroll in this dimension, wrap instead using UNSPECIFIED.ci

它想表达的是:在可滚动的ViewGroup中,不该该限制 Item 的尺寸(若是是水平滚动,就不限制宽度),为何呢? 由于是能够滚动的,就算 Item 有多宽,有多高,经过滚动也同样能看到滚动前被遮挡的部分。get

这里其实也就回答了我以前询问的 NestedScrollView 要强行设置 Item 为 UNSPECIFIED 的缘由。
有同窗可能会有疑问: 我设置 wrap_content,在 onMeasure() 中应该收到的是 AT_MOST 才对啊,为何要强制变成 UNSPECIFIED源码

这是由于考虑到 Item 的尺寸有可能超出这个可滚动的 ViewGroup 的尺寸,而在 AT_MOST 模式下,你的尺寸不能超出你所在的 ViewGroup 的尺寸,最多只能等于,因此用 UNSPECIFIED会更合适,这个模式下你想要多大就多大。it

那么,咱们在自定义 View 的时候,在测量时发现是 UNSPECIFIED 模式时,应该怎么作呢?io

这个就比较自由了,既然尺寸由本身决定,那么我能够写死为 50,也能够固定为 200。但仍是建议结合实际需求来定义咯。容器

好比 ImageView,它的作法就是:有设置图片内容(drawable)的话,会直接使用这个 drawable 的尺寸,但不会超过指定的 MaxWidthMaxHeight, 没有内容的话就是 0。而 TextView 处理 UNSPECIFIED 的方式,和 AT_MOST 是同样的。

固然了,这些尺寸都不必定等于最后 layout 出来的尺寸,由于最后决定子 View 位置和大小的,是在 onLayout() 方法中,在这里你彻底能够无视这些尺寸,去 layout()成本身想要的样子。不过,通常不会这么作。

相关文章
相关标签/搜索