我眼中的View

1.每个View都只有一个父View

2.整个视图只有一个根View

 

3.DecorView --- FrameLayout

 3.1我们在写视图的时候,要尽可能的少写视图层级

 3.2能用FrameLayout写的,就不要用RelativiLayout,能用RelativiLayout写的,就不要用LinearLayout。

 

 4.我们通过setContentView设置的View并不是最跟View。

  4.1 隐藏标题栏需要在setContentView之前设置。

 

 5.一个View如何显示到屏幕上来

  5.1 view有多大-- measure --- onMeasure

  5.2 view的位置在哪儿  -- layout  --- onLayout

  5.3 view长什么样子-- draw  --- onDraw

 

 6.不是所有的View都能添加子View

  6.1 就是ViewGroup的子类,因为只有ViewGroup实现了ViewParent接口

  6.2 我们通过getParent拿到的虽然是ViewParent,但是在它不为null的前提下,我们可以放心的强转为ViewGroup

 

7. measure

    只有View有这个方法,ViewGroup没有重载

    测量自身的大小

 

MeasureSpec:用来辅助计算View的大小

   View.MeasureSpec.AT_MOST;// 最大

    View.MeasureSpec.EXACTLY;//精确

    View.MeasureSpec.UNSPECIFIED;//未知

    目前未知没有使用,因为每一个View被添加到视图上时,都必须制定宽高,就算你不指定,也会有一个默认的(每个ViewGroup生成默认宽高都不一样)

 

    通过MeasureSpec.makeMeasureSpec() 来合成模式和宽高

    通过MeasureSpec.getMode和MeasureSpec.getSize 来获取模式和宽高

 

    代码中设置View的宽和高必须要通过LayoutParams来设置,所有影响子View和父View之间的关系的属性全部需要通过LayoutParams来设置,也可以根据xml布局中属性名是否带有layout_开头来判断

 

    LayoutParams有很多种类,基本上是每一种布局都有一个自己的实现,因为每个布局都有各自的特征,没办法用一个统一类来描述

 

如果父亲的mode是 EXACTLY, 子View是WRAP_CONTENT  那么mode 是AT_MOST, size 是父亲的最大size。

如果父亲的mode是 EXACTLY, 子View是MATH_PARENT   那么mode 是EXACTLY, size 是父亲的最大size。

如果父亲的mode是 EXACTLY, 子View是DIP           那么mode 是EXACTLY, size 是DIP。

 

如果父亲的mode是 AT_MOST,  子View是WRAP_CONTENT  那么mode 是AT_MOST, size 是父亲的最大size。

如果父亲的mode是 AT_MOST,  子View是MATH_PARENT   那么mode 是EXACTLY, size 是父亲的最大size。 // ---(大多数View实现都是EXACTLY,但是有些View实现是AT_MOST,我们要尽量避免这种情况)

如果父亲的mode是 AT_MOST,  子View是DIP           那么mode 是EXACTLY, size 是DIP。

 

如果你设定宽高为MATH_PARENT 或者 DIP 则模式为 EXACTLY,如果是WRAP_CONTENT,则为AT_MOST

如果你设定的宽高为DIP,那么你的size就是dip,其他情况都是父View的最大值,或者父View剩余的最大值

 

 

View内部是如何测量自身的

    如果是一个包括内容的(540,50);

    1.它会测量自己的背景图片   100*100

    2.TextView  测量文字

        ImageView测量自身的图片   200*200;  ---> 50

 

    200 200

ViewGroup --> 100 * 100

        100 * 100

    ViewGroup--> wrap wrap  AT_MOST|100

            100*100

        ImageView是包裹内容的,但是设置的图片 200*200; AT_MOST|100

                100*100

如果自身测量的结果大于父View传递过来的参数,并且模式是AT_MOST的时,它会选择一个较小的值

 

onMeasure

    7.1 在一个View中,它是用来测量自身的大小,实际上就是设置自身的大小

    7.2 在ViewGroup中,它通过onMeasure来测量子View的大小,并通过子View的大小来设置自身的大小。

    view.measure(int,int);

 

8.layout(l,t,r,b)

    在View中,是用来指定一个View的上下左右四个点,ViewGroup中没有重载

    首先它用临时变量记录自己上一次的l,t,r,b,然后比较这一次的l,t,r,b。

    if(l !=l || t !=t || r != r || b != b){

        boolean changed = onSizeCHange

    }

 

  onLayout(changed)

     8.1 在View中,它是空实现。因为一个View的位置是由它的父亲指定的。

     8.2 在ViewGroup中,它是用来确定所有子View的位置。

     ViewGroup的子类一般怎么实现该方法

        LinearLayout --> 检查自身的方向orientation,判断是横向还是纵向

        for循环遍历所有的子View。为子View准备l,t,r,b

            如果是横向的,一般第一个View的l就是0,t就是0,r就是该View的宽度,b就是该View的高度。后面的View的l会等于前一个View的r。

 

        RelativiLaytout --> for循环所有的子View。为子View准备l,t,r,b

            首先它会获取这个子View的params,然后进行一些列的判断,根据其他子View确定该View的位置。

 

        FrameLayout --> for循环所有的子View。为子View准备l,t,r,b

            它就判断gravity,如果是start,就从左上角开始布局,

            一般情况下,所有的子View都具备相同的l,t

 

 

9. draw

    在View中,它是用来画一些通用的东西的。

    如果你是View,它就会调用你的onDraw方法,

    如果你是ViewGroup,它就会调用你的dispatchDraw

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值