美文网首页安卓
自定义ViewGroup的知识点总结-持续更新

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

作者: tinyvampirepudg | 来源:发表于2021-07-16 14:32 被阅读0次

    自定义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等自定义布局,都可以这么实现。

    未完待续,敬请期待。

    相关文章

      网友评论

        本文标题:自定义ViewGroup的知识点总结-持续更新

        本文链接:https://www.haomeiwen.com/subject/qyhspltx.html