zoukankan      html  css  js  c++  java
  • Layout布局源码浅析之——FrameLayout

    一直想研究下安卓各种布局控件,FrameLayout是安卓最简单的界面布局,所以就从FrameLayout讲起。

    1.属性。frameLayout继承ViewGroup,除了拥有ViewGroup的属性之外,只有一个layout_gravity属性。看它的内部静态类LayoutParams:

     
    1 public static class LayoutParams extends MarginLayoutParams {  
    2     public int gravity = -1;//唯一的属性  

    2.绘制过程。首先,它会遍历所有子view,并且对每个子view进行measure,并记录下子view的最大宽高,作为自身的尺寸。在这个过程中,如果自身是不确定大小的模式,子view又是MATCH_PARENT属性的,就需要为这些子view重新测绘。

     1 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
     2        (。。。。。。)  
     3   
     4        int maxHeight = 0;//记录最大的宽高  
     5   
     6        int maxWidth = 0;  
     7        int childState = 0;  
     8   
     9        for (int i = 0; i < count; i++) {  
    10            final View child = getChildAt(i);  
    11            if (mMeasureAllChildren || child.getVisibility() != GONE) {  
    12                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);//测绘所有子view  
    13                final LayoutParams lp = (LayoutParams) child.getLayoutParams();  
    14                maxWidth = Math.max(maxWidth,  
    15                        child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);  
    16                maxHeight = Math.max(maxHeight,  
    17                        child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);  
    18                childState = combineMeasuredStates(childState, child.getMeasuredState());  
    19                if (measureMatchParentChildren) {  
    20                    if (lp.width == LayoutParams.MATCH_PARENT ||  
    21                            lp.height == LayoutParams.MATCH_PARENT) {  
    22                        mMatchParentChildren.add(child);//保存需要重新测绘的子view  
    23                    }  
    24                }  
    25            }  
    26        }  
    27   
    28     (。。。。。。)  
    29        if (count > 1) {  
    30            for (int i = 0; i < count; i++) {  
    31               <pre name="code" class="java" style="font-size: 13.3333px;">     (。。。。。。)  
    32 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);//重新测绘子view } } }

    3.layout过程。FrameLayout对每个子view的layout过程是相同的。它遍历所有子view,通过子view的gravity属性进行xy轴偏移量的计算,最后调用child.layout()对子View进行布局。

     1 void layoutChildren(int left, int top, int right, int bottom,  
     2                                   boolean forceLeftGravity) {  
     3         (。。。。。。)  
     4   
     5         for (int i = 0; i < count; i++) {  
     6             (。。。。。。)  
     7   
     8                 switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {  
     9                     case Gravity.CENTER_HORIZONTAL:  
    10                         childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +  
    11                         lp.leftMargin - lp.rightMargin;  
    12                         break;  
    13                     case Gravity.RIGHT:  
    14                         if (!forceLeftGravity) {  
    15                             childLeft = parentRight - width - lp.rightMargin;  
    16                             break;  
    17                         }  
    18                     case Gravity.LEFT:  
    19                     default:  
    20                         childLeft = parentLeft + lp.leftMargin;  
    21                 }  
    22   
    23                 switch (verticalGravity) {  
    24                     case Gravity.TOP:  
    25                         childTop = parentTop + lp.topMargin;  
    26                         break;  
    27                     case Gravity.CENTER_VERTICAL:  
    28                         childTop = parentTop + (parentBottom - parentTop - height) / 2 +  
    29                         lp.topMargin - lp.bottomMargin;  
    30                         break;  
    31                     case Gravity.BOTTOM:  
    32                         childTop = parentBottom - height - lp.bottomMargin;  
    33                         break;  
    34                     default:  
    35                         childTop = parentTop + lp.topMargin;  
    36                 }  
    37   
    38                 child.layout(childLeft, childTop, childLeft + width, childTop + height);  
    39             }  
    40         }  
    41     }  
  • 相关阅读:
    句子反转
    python中计时模块timeit的使用方法
    python入门(一)
    将小程序的API封装成支持Promise的API
    微信小程序实现导航功能的操作步骤
    微信小程序朋友转发和朋友圈分享
    js原生上传图片
    FormData
    原生 websocket
    判断手机终端是pc还是移动端,并自动跳转
  • 原文地址:https://www.cnblogs.com/linghu-java/p/9157553.html
Copyright © 2011-2022 走看看