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

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

未完待续,敬请期待。

相关文章
|
7月前
Android4.1.0实战教程---自动阅读小说
Android4.1.0实战教程---自动阅读小说
92 1
|
4月前
|
存储 缓存 移动开发
EaselJS 源码分析系列--第二篇
EaselJS 源码分析系列--第二篇
|
4月前
|
移动开发 前端开发 JavaScript
EaselJS 源码分析系列--第一篇
EaselJS 源码分析系列--第一篇
|
4月前
|
存储 前端开发 JavaScript
PixiJS源码分析系列: 第一章 从最简单的例子入手
PixiJS源码分析系列: 第一章 从最简单的例子入手
|
4月前
|
存储 前端开发 JavaScript
EaselJS 源码分析系列--第四篇
EaselJS 源码分析系列--第四篇
|
存储 移动开发 JSON
前端面试题汇总大全 -- 持续更新!(一)
前端面试题汇总大全 -- 持续更新!
437 0
|
算法 网络协议 Java
Android面试知识点复习手册(收藏)
Android面试知识点复习手册(收藏)
134 0
|
存储 缓存 JavaScript
前端面试题汇总大全 -- 持续更新!(二)
前端面试题汇总大全 -- 持续更新!
91 0
|
存储 缓存 JSON
前端面试题汇总大全 -- 持续更新!(四)
前端面试题汇总大全 -- 持续更新!
104 0
|
移动开发 编解码 前端开发
前端面试题汇总大全 -- 持续更新!(三)
前端面试题汇总大全 -- 持续更新!
89 0