自定义ViewGroup的知识点总结-持续更新

自定义ViewGroup的知识点总结-持续更新

1、child.getMeasuredWidth()中会包含child的padding值

child的margin的值需要自行适配。

2、在onMeasure方法中:

需要先对child进行measure,然后才能获取到measuredWidth和measureHeight。

常用的测量方法有两个:
ViewGroup#measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec)

ViewGroup#measureChildWithMargins(View child,int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)

但是measureChildWithMargins有个缺陷,它内部的MarginLayoutParams是类型强转而来的,没有添加非空判断和类型判断,如果我们是自定义ViewGroup,这里会就有可能导致空指针和类型转换异常,为了解决这个问题,我自定义了一个方法,具体请看下面的measureChildWithMarginsAndUsedSpace方法。

3、测量child时,考虑到measureChildWithMargins的缺陷,这里自行实现了一个方法:measureChildWithMarginsAndUsedSpace

protected void measureChildWithMarginsAndUsedSpace(View child,
                                                   int parentWidthMeasureSpec, int widthUsed,
                                                   int parentHeightMeasureSpec, int heightUsed) {
    // 兜底,不会发生
    if (child.getLayoutParams() == null) {
        return;
    }
    final LayoutParams lp = child.getLayoutParams();


    int paddingH = getPaddingLeft() + getPaddingRight() + widthUsed;
    int paddingV = getPaddingTop() + getPaddingBottom() + heightUsed;


    if (child.getLayoutParams() instanceof MarginLayoutParams) {
        final MarginLayoutParams mlp = (MarginLayoutParams) child.getLayoutParams();
        paddingH += mlp.leftMargin + mlp.rightMargin;
        paddingV += mlp.topMargin + mlp.bottomMargin;
    }


    final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, paddingH, lp.width);
    final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, paddingV, lp.height);


    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}

4、自定义ViewGroup时,必须考虑自身的padding,以及child的padding、margin等。

如果child也是自定义ViewGroup,那么也需要考虑因素。

5、如何方便的支持child的margin数据?重写ViewGroup#generateLayoutParams方法即可

@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new MarginLayoutParams(getContext(), attrs);
}

ViewGroup只提供了ViewGroup.LayoutParams,MarginLayoutParams是各个ViewGroup自行继承实现的。

我们的ViewGroup要支持MarginLayoutParams最好的方式,就是重写ViewGroup#generateLayoutParams方法。

6、对于一些需要限制宽度的操作,可以在onMeasure中操作。

先测量出实际宽度,如果超出了预期,再根据其最大长度进行二次测量即可。
常见的FlowLayout等自定义布局,都可以这么实现。

未完待续,敬请期待。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

tinyvampirepudge

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

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

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

打赏作者

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

抵扣说明:

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

余额充值