• View的layout机制


    View框架的工作流程为:测量每个View大小(measure)-->把每个View放置到相应的位置(layout)-->绘制每个View(draw)。

    源代码分析

       在View的源代码中,提取到了下面一些关于layout过程的信息。

       我们知道,整棵View树的根节点是DecorView,它是一个FrameLayout,所以它是一个ViewGroup,所以整棵View树的测量是从一个ViewGroup对象的layout方法开始的。

    View:

    1、layout

    //分配一个位置信息到一个View上面,每个parent会调用children的layout方法来设置children的位置。最好不要覆写该方法,有children的viewGroup,应该覆写onLayout方法

    public void layout(int l, int t, int r, int b) ;

    2、onLayout

    /** 根据布局规则,计算每一个子View的位置,View类默认是空实现。 所以这里没有源代码*/
    protected void onLayout(boolean changed, int left, int top, int right, int bottom);

    ViewGroup:

    ViewGroup中,只需要覆写onLayout方法,来计算出每一个子View的位置,并且把layout流程传递给子View。源代码:
    ViewGroup没有实现,具体可以参考LinearLayout和RelativeLayout的onLayout方法。虽然各个具体实现都很复杂,但是基本流程是一样的,可以参考下面的伪代码。

    protected void onLayout(boolean changed, int l, int t, int r, int b) {  
        for (遍历子View) {  
            /** 
            根据如下数据计算。 
                1、自己当前布局规则。比如垂直排放或者水平排放。 
                2、子View的测量尺寸。 
                3、子View在所有子View中的位置。比如位置索引,第一个或者第二个等。 
            */  
            计算每一个子View的位置信息;   
              
            child.layout(上面计算出来的位置信息);  
        }         
    }  
    


    结论

            一般来说,自定义View,如果该View不包含子View,类似于TextView这种的,是不需要覆写onLayout方法的。而含有子View的,比如LinearLayout这种,就需要根据自己的布局规则,来计算每一个子View的位置。

  • 相关阅读:
    git pull fatal: refusing to merge unrelated histories
    Git报错:Your branch is ahead of 'origin/master' by 1 commit
    java读取大文件内容到Elasticsearch分析(手把手教你java处理超大csv文件)
    Java try catch语句块中try()的括号中代码作用
    Redis这15个“雷坑”,别问我咋知道的……
    MySql死锁
    MQ限流应用
    什么是 JWT -- JSON WEB TOKEN
    mybatis-plus查询指定字段
    数据库炸了----我就重启了一下啊(Communications link failure)
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/6539986.html
Copyright © 2020-2023  润新知