Android自定义控件之onLayout详解 - Go语言中文社区

Android自定义控件之onLayout详解


    上一篇我们分析了onMeasure的具体调用流程,这里我们接着分析自定义控件的另一个方法:onlayout,onLayout的目的是确定子View在父View中的位置,因此我们的分析还是从ViewGroup的代表Linealayout为入口分析整个过程。

一.源码分析

    Linealayout的onLayout方法如下:
还是同样的分了两个方向,我们用垂直方向来做代表进行分析,由于代码过长我们就分段分析:
     整个过程都在计算ChildView的左上的坐标,先确定有子View的数量然后根据Gravity来确定第一个控件左上坐标的初始值,这里我们先说明一下View是如何确定位置的,借用一个大佬的图:
    从上图可以看出控件的位置是通过左上和右下两个坐标来确定的,坐标的原点在左上角,正坐标方向为向右和向下,接着我们再看后面的代码:
    这里遍历了子View然后单个进行计算,计算过程先利用getMeasureWidth/Height()来获得View的宽高,这里后续还会讲到为什么用这个方法。接着就是结合Gravity来计算childLeft和childTop,然后调用setChildFrame,传入左上角坐标和宽高,最后由于我们是分析垂直方向,因此最后要叠加childTop。接下来我们接着进入setChildFrame
    这里的方式onMeasure的实现方法一直,这里调用了子View的layout方法,再调用onLyout方法,而且在onLyout方法中没有任何实现,也就是说实际上ViewGroup是依靠onlayout方法来确定子View所处位置,而View则依靠layout方法来决定自身位置。

二.getMeasureWidth()和getWidth()区别  

         在自定义View时很多新手会使用getWidth()方法来获取宽度,然后返回的都是0,这里我们具体分析一下两个方法的区别,便于理解。

    1.getMeasureWidth()

        这里有两个参数,后者是个常量,我们就看前者什么时候开始赋值:

查看该方法调用:

    这里分两条路,我们就兵分两路去看:

(1)第一条:

    第一条回到了measure方法中,这里先不做分析,我们再看第二条。

(2)第二条:


   


    这里看到最终还是回到了measure方法中,面的最后一张图实际上就是我们分析的两条路,因此getMeasureWidth方法有值返回时在onMeasure以后。

    2.getWidth()

  

这里有两个值,看什么时候初始化:


    从这里能看到最终是在View的layout方法中调用并初始化的,这里也是分了两条,从下图也能看出,前者方法实际上也是调用setFrame方法,因此最终还是在layout方法中才能初始化。

    综合上面分析我们得出结论,getMeasureWidth()在ViewGroup调用onMeasure以后就能获得值,而getWidth()要在View调用layout方法以后,所以为什么自定义VeiwGroup的onLayout方法只能调用getMeasureWidth()。

    本篇文章我们分析了onLayout的具体实现过程,总体来说onLayout的实现思路和onMeasure是一致的,就是ViewGroup先计算,然后调用View的方法,最终确定View的最终位置。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_36120901/article/details/79789240
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-18 21:38:32
  • 阅读 ( 741 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢