美文网首页Android 自定义View
Android MeasureSpec - View

Android MeasureSpec - View

作者: D13954 | 来源:发表于2019-06-12 15:32 被阅读0次

MeasureSpec 是一个 32 位的 int 类型,并且取了最前面的两位代表 Mode,后 30 位代表大小 Size。

3种模式

EXACTLY(精确模式,在这种模式下,尺寸的值是多少,那么这个组件的长或宽就是多少,对应 MATCH_PARENT 和确定的值)

AT_MOST(WRAP_CONTENT,最大就是父控件的大小)

UNSPECIFIED(当前组件,可以随便用空间,不受限制,系统用,具体就体现在 NestedScrollView 和 ScrollView 中)

我们开发中,常用AT_MOST,EXACTLY

我们可能会给定默认大小,或者根据内容变化,经常都是固定大小

根视图
ViewRoot - performTraversals(执行遍历)

ViewGroup 还需要负责通知自己的子 View 进行绘制操作

private void performTraversals() {
    ...
    int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
    int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
    ...
    //执行测量流程
    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    ...
    //执行布局流程
    performLayout(lp, desiredWindowWidth, desiredWindowHeight);
    ...
    //执行绘制流程
    performDraw();
}

onMeasure

每个 View 都有自己的大小,所以基本自定义 View 的时候都需要重写 onMeasure() 这个方法,以定制化我们的 View 的宽高

如果不重写这个方法,我们通常会出现 wrap_content 和 match_parent 是一样的显示效果

View 默认是会使用 getDefaultSize() 方法进行设置宽高的,在 AT_MOST和 EXACTLY 两种情况下都会直接使用测量规格里面的尺寸

在 ViewGroup 中,并没有去重写 View 的 onMeasure() 方法,而这都需要它的子类根据自己的逻辑去实现
ViewGroup 提供了一个 measureChildren() 方法来依次遍历每个子 View 对其进行测量。
在经过 onMeasure() 操作后,getMeasureWidth() 和 getMeasureHeight() 方法就可以拿到正确的返回值了

由于 View 的 measure 过程和 Activity 的生命周期方法不是同步执行的,如果 View 还没有测量完毕,那么获得的宽/高就是 0。所以在 onCreate()、onStart()、onResume() 中均无法正确得到某个 View 的宽高信息。可以通过在 onWindowFocusChanged() 判断获取到焦点后进行获取,或者使用 view.post()方式。

onLayout

onLayout() 方法主要作用是确定子 View 的显示位置,由于 View 已经是最小的层级,所以我们在自定义 View 的时候通常不需要管这个方法,而在自定义 ViewGroup 的时候就不得不注意这个方法
通过确认left,top,right,bottom四个值,确定了view的大小
获取view的大小,可以在onSizeChange之后

draw

drawBackground()
onDraw()
dispatchDraw()
onDrawScrollbars()

通常我的内容就是在draw中,代码编写也是主要在这里

相关文章

网友评论

    本文标题:Android MeasureSpec - View

    本文链接:https://www.haomeiwen.com/subject/tldlfctx.html