Android自定义控件入门到精通--View树的布局

《Android自定义控件入门到精通》文章索引 ☞ https://blog.csdn.net/Jhone_csdn/article/details/118146683

《Android自定义控件入门到精通》所有源码 ☞ https://gitee.com/zengjiangwen/Code

View树的布局

经过前面View树的绘制流程View树的测量流程的学习,相信大家自己分析View树的布局流程已经没有什么难度了

ViewRootImpl.java

//ViewRootImpl.java
private void performTraversals() {
   
    //测量流程
	measureHierarchy(...)-->performMeasure(...);
    //布局流程
    performLayout(...);
    //绘制流程
     performDraw();
}

布局的操作是针对ViewGroup而言,且直接在onLayout()方法中实现就行了:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
   

}

LayoutParams

我们能用view.getLayoutParams()获取到布局参数LayoutParams,那么,这个对象是怎么生成的?

ViewGroup.java

//ViewGroup.java
public void addView(View child, int index) {
   
    if (child == null) {
   
        throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
    }
    LayoutParams params = child.getLayoutParams();
    if (params == null) {
   
        params = generateDefaultLayoutParams();
        if (params == null) {
   
            throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
        }
    }
    addView(child, index, params);
}
//生成Child的布局参数对象LayoutParams
protected LayoutParams generateDefaultLayoutParams() {
   
    return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}

可以看到,当ViewGroup添加Child的时候,是通过generateDefaultLayoutParams()来生成Child的LayoutParams对象的

当时翻看LayoutParams类的时候发现,它里面只有width、height两个属性

public static class LayoutParams {
   
	public int width;
    public int height;
}

我们知道:

  • Child跟Parent相关的布局属性是放在LayoutParams中的,比如Child的width、height、margin
  • Child的padding是跟Parent无关的,它属于width/height的一部分,通过child.getPadding就可以获取

那Child的margin值,我们怎么获取到呢

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nYh58Pe6-1624353180372)(…/img/image-20210621103312840.png)]

在ViewGroup中,还提供了一个MarginLayoutParams

 public static class MarginLayoutParams extends ViewGroup.LayoutParams {
   
 	public int leftMargin;
 	public int topMargin;
 	public int rightMargin;
 	public int bottomMargin;
 }

那么,我们在自己自定义的ViewGroup中,返回MarginLayoutParams不就可以了吗

protected LayoutParams generateDefaultLayoutParams() {
   
    return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}

然后通过xml等方式设置的margin值,就可以被MarginLayoutParams解析了

public MarginLayoutParams(Context c, AttributeSet attrs) {
   
        super();

        TypedArray a = c.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一鱼浅游

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值