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

未完待续,敬请期待。

相关文章
|
2月前
|
Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
4月前
|
存储 缓存 移动开发
EaselJS 源码分析系列--第二篇
EaselJS 源码分析系列--第二篇
|
4月前
|
存储 前端开发 JavaScript
EaselJS 源码分析系列--第四篇
EaselJS 源码分析系列--第四篇
|
4月前
|
移动开发 前端开发 JavaScript
EaselJS 源码分析系列--第一篇
EaselJS 源码分析系列--第一篇
|
4月前
|
存储 前端开发 JavaScript
PixiJS源码分析系列: 第一章 从最简单的例子入手
PixiJS源码分析系列: 第一章 从最简单的例子入手
|
存储 编解码 前端开发
W3Cschool编程实战教程中BootStrap相关基础知识点总结
1、通过Bootstrap,我们只要给图片添加 img-responsive 的class属性,图片的宽度就能自动适配你手机屏幕的宽度啦。
64 0
|
SQL JSON Java
入门案例(项目搭建)|学习笔记
快速学习入门案例(项目搭建)
入门案例(项目搭建)|学习笔记
|
JavaScript 索引
WebApi入门第十二章(原生轮播图 )(完结)
WebApi入门第十二章(原生轮播图 )(完结)
128 0
WebApi入门第十二章(原生轮播图 )(完结)
|
XML API Android开发
Preference组件探究之源码解读
Preference组件探究之源码解读
自定义View | ofObject详解与实战(ValueAnimator进阶)
自定义View | ofObject详解与实战(ValueAnimator进阶)