美文网首页
view-layout过程

view-layout过程

作者: 刘佳阔 | 来源:发表于2018-03-09 11:17 被阅读0次

1.layout总体流程和measure过程是类似的.都是在ViewRootImpl.performTraversals中调用host的方法.host的layout方法不建议子视图重写.子视图应该重写onLayout方法来实现布局过程.其实最终都是通过调用setFrame()函数来设定自己在父视图中的位置


1.png

2.View.layout函数中先调用setFrame()指定了该视图在父视图中左上右下的位置,并把这些位置保存在该视图中.然后调用onlayout()函数,VieGroup必须重写该函数对子视图进行layout.然后就是通知OnLayoutChangeListener发生了layout变化.
3.下边看下LinearLayout的onLayout过程,竖直方向上的

    void layoutVertical(int left, int top, int right, int bottom) {//1.形参是该lInearLayout父视图在他的父视图中的位置.左上右下.
        final int paddingLeft = mPaddingLeft;
        int childTop;
        int childLeft;
        
        // Where right end of child should go
        final int width = right - left; //2.父视图的宽度
        int childRight = width - mPaddingRight; //3.子视图right的最大值就是父视图的宽度-paddingright
        
        // Space available for child
        int childSpace = width - paddingLeft - mPaddingRight; //4.子视图的最大宽度
        
        final int count = getVirtualChildCount();//5.子视图的数量

        final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
        final int minorGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;

        switch (majorGravity) { //6.根据父视图的gravity值.计算子视图的top的值.这里是竖直方向上的
           case Gravity.BOTTOM:
               // mTotalLength contains the padding already
               childTop = mPaddingTop + bottom - top - mTotalLength;
               break;

               // mTotalLength contains the padding already
           case Gravity.CENTER_VERTICAL:
               childTop = mPaddingTop + (bottom - top - mTotalLength) / 2;
               break;

           case Gravity.TOP:
           default:
               childTop = mPaddingTop;
               break;
        }

        for (int i = 0; i < count; i++) {//7.根据子视图的layout_gravity值.计算每个子视图在水平方向上的left值
            final View child = getVirtualChildAt(i);
      if (child.getVisibility() != GONE) {
                final int childWidth = child.getMeasuredWidth();
                final int childHeight = child.getMeasuredHeight();
                
                final LinearLayout.LayoutParams lp =
                        (LinearLayout.LayoutParams) child.getLayoutParams();
                
                int gravity = lp.gravity;//8因为这里取的是LayoutParams 的gravity,而LayoutParams 是父视图调用addView()添加子视图时
      为子视图创建的.所以这里的值是子视图的layout_gravity属性的值,而不是子视图的gravity的值.并且,gravity也并不影响子视图的位置,它只
      影响子视图中内容的位置.
                if (gravity < 0) {
                    gravity = minorGravity;
                }
                final int layoutDirection = getLayoutDirection();
                final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
                switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                    case Gravity.CENTER_HORIZONTAL:
                        childLeft = paddingLeft + ((childSpace - childWidth) / 2)
                                + lp.leftMargin - lp.rightMargin;
                        break;

                    case Gravity.RIGHT:
                        childLeft = childRight - childWidth - lp.rightMargin;
                        break;

                    case Gravity.LEFT:
                    default:
                        childLeft = paddingLeft + lp.leftMargin;
                        break;
                }

                if (hasDividerBeforeChildAt(i)) {
                    childTop += mDividerHeight;
                }

                childTop += lp.topMargin;
                setChildFrame(child, childLeft, childTop + getLocationOffset(child),
                        childWidth, childHeight);//9.为子视图设置他在父视图中的位置.这里调用了子视图的layout()方法递归layout过程.
                childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child);

                i += getChildrenSkipCount(child, i);
            }
        }
    }

注意.任何view的layout_ 之类的属性,都是在这个view的父视图addView()时,通过调用generateLayoutParams(attr)来生成的.此时的attr就是子视图的layout_属性,换句话说.父视图为子视图创建layoutParams. 而创建layoutParams所需要的参数来自子视图自己的定义.同时这也意味着.如果你单纯的只写一个view.而不包括父视图.那么他的layout_相关的属性都不会起作用

相关文章

  • view-layout过程

    1.layout总体流程和measure过程是类似的.都是在ViewRootImpl.performTravers...

  • View-Layout注入框架--简洁视图注入

    框架开发前 在没有这套框架之前,我们在activity、fragment、自定义view、listview的vie...

  • 过程,过程,过程

    慎重的对待那些过程,因为过程影响最后的结果! “小明呀,今天你要把这件事情前前后后地梳理一遍哈。”“小明呀,这个问...

  • 过程都是好过程

    最近看了半年多前就很火的电视剧《我的前半生》,之前只看了几集,也不知哪来的心情还想起这部电视剧。 看了这部电视剧,...

  • 过程

    自我人格还未完全形成时期,要远离错误的环境

  • 过程

    作者-林白 一月你还没有出现 二月你睡在隔壁 三月下起了大雨 四月里遍地蔷薇 五月我们面对面坐着,犹如梦 就这样六...

  • 过程

    一月,你还没有出现 二月,你睡在隔壁 三月,下起了大雨 四月里,遍地蔷薇 五月,我们对面坐着 犹如梦中 就这样六月...

  • 过程

    “我怀念的,是无话不说。” 作者/春梅 羚城 小雨宜 翻看日记本忌 出门忘记带伞 一月 这一年怎么开始 我窝在家里...

  • 过程

    一个身沐朝霞的人 短视是致命危险 坐在情绪的断崖边 等待寓言中标志明确目的性的存在 那些路都闪着光 择一而行 时刻...

  • 过程

    心好疼,想哭,要流泪,怎么办很努力画画试试。分散注意力。要求自己在16点前只能画画,不能想他们的事,不能想伤害。我...

网友评论

      本文标题:view-layout过程

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