自定义ViewGroup可不像自定义View那么简单
今日聚焦:
1.自定义ViewGroup中花样布局子View2.移动View用layout、translation、TranslationAnimation、ViewPropertyAnimator、scrollTo、scrollBy有什么区别?3.ViewGroup里怎么给孩子加动画4.惯性移动? 也许你可以了解一下复制代码
效果 1
效果 2
一、前置知识:
1.生命函数
这是我曾经测试画出的一张图,描述了ViewGroup+两个孩子的生命函数调用情况
在这补充一点,ViewGroup在没有背景时不会走onDraw方法,但可以走dispatchDraw原因在于View对onDraw的控制时做了限定:[if(!dirtyOpaque) onDraw(canvas)] 你可以使用onDraw,在之前设个透明色即可:setBackgroundColor(0x00000000);
![](https://img.haomeiwen.com/i15405328/8d4191dd8773e5a3.png)
2.View与Activity之间
貌似一直没有对Activity与View的生命周期一起做过测试
测试之后发现View加载完成之后(onFinishInflate)并未立即回调测量、布局、绘制
而是在onResume之后View才会回调onAttachedToWindow-->onMeasure-->onSizeChanged-->onLayout-->onDraw
这一点确实让我挺惊讶,以前竟然没注意,现在理清了,通畅很多
2019-02-19 16:50:29.998 : onCreate --------------
2019-02-19 16:50:29.992 : 构造函数: 0
2019-02-19 16:50:29.996 : onFinishInflate: 0
2019-02-19 16:50:33.001 : onStart: ...................
2019-02-19 16:50:33.006 : onResume: ...................
2019-02-19 16:50:33.050 : onAttachedToWindow:
2019-02-19 16:50:33.207 : onMeasure: 0
2019-02-19 16:50:33.243 : onMeasure: 0
2019-02-19 16:50:33.354 : onSizeChanged: 1948
2019-02-19 16:50:33.358 : onLayout: 1948
2019-02-19 16:50:33.395 : onDraw: 1948
二、自定义ViewGroup (排兵布阵)
经测试发现注意点:
[1].必须onMeasure中测量孩子的尺寸,否则无法显示
[2].必须onLayout中布局孩子的位置,否则无法显示
[3].在onLayout中孩子不能用view.getHeight()获取尺寸(因为为0),只能用view.getMeasuredHeight复制代码
1.最简形式的ViewGroup
这里使用适配器模式,跟ListView一个套路,其实是非常简单,看箭头所指
这里暂时不对ViewGroup进行测量,先填满。对子View用自带的测量方法measureChildren
![](https://img.haomeiwen.com/i15405328/472f7e3cdf1325fa.png)
2.布局子view
这里关键在排布这里给张图先:子View布局的左上右下
![](https://img.haomeiwen.com/i15405328/84cc221cc6fbbd09.png)
![](https://img.haomeiwen.com/i15405328/ad7466034c6318d7.png)
![](https://img.haomeiwen.com/i15405328/c7bfacda292edf0a.png)
3.放置成圆形
![](https://img.haomeiwen.com/i15405328/e892fa46cfb2e5de.png)
![](https://img.haomeiwen.com/i15405328/93e0b17d89612b9f.png)
![](https://img.haomeiwen.com/i15405328/005149c6d2269742.png)
4.添加点击事件
这就比较容易了,一个监听搞定
![](https://img.haomeiwen.com/i15405328/0481b8a27cea2b7d.png)
5.数组点阵定位
这突然让我想到一个好玩的东西,那就是点阵控位。
点阵控位可以使用二维数组,也可以使用字符串,也可以使用像素点。
具体的可以详见我的这篇:这里就放一张核心的分析图:我们这里不画圆,而是取点位
![](https://img.haomeiwen.com/i15405328/ec8336f69b3d16c9.png)
![](https://img.haomeiwen.com/i15405328/5ed1afb3cbbe9c31.png)
![](https://img.haomeiwen.com/i15405328/6d0c84e9f7e68e91.png)
ok了,只要把1放在你想要的位置,子View就在那里,
不过简单一点的还好说,要是爱心...来看神技:
5.位图点阵定位
用黑白(就相当于上面1,0)来标识点位,再根据Bitmap的像素进行
Bitmap内存杀手? 7*7像素的Bitmap也就九牛一毛...
就是下面的小不点,你可以下载玩玩。有PS,你也可以用ps自己戳点
![](https://img.haomeiwen.com/i15405328/90adef4671ee199f.png)
![](https://img.haomeiwen.com/i15405328/eda912bfa5c7f20a.png)
到这里排兵布阵就结束了,相信对onLayout已经能玩的6了吧,接下来上阵杀敌。
二.移动测试篇
既然是测试,就一切从简,直切问题本身,这里新建了一个Activity
并且打开了手机自带的布局便界显示,这样更能说明问题所在
1.布局
自定义:TestViewGroup+TestView纯原生,不加防腐剂
为了说明问题,这里的TestViewGroup加了边距
![](https://img.haomeiwen.com/i15405328/1003255d1ccc954b.png)
![](https://img.haomeiwen.com/i15405328/5e359178e955a026.png)
2.代码实现
![](https://img.haomeiwen.com/i15405328/56c7389d4cb879a0.png)
3.移动:layout与translation
这样对比应该非常明显:layout真的把布局移动了,translation只是离家出走而已
layout-----
translation
点击事件在绿色上点击事件在绿色上
![](https://img.haomeiwen.com/i15405328/05161b289b6c9d78.png)
4 : 移动动画和属性动画
移动动画都是从家里开始,属性动画移动从当前位置,但是家还在那里!
也就是传说中的属性动画也并无法改变View的布局位置
TranslationAnimation
ViewPropertyAnimator
点击事件在家里点击事件在绿色上
![](https://img.haomeiwen.com/i15405328/5066fb3d87f30225.png)
5:哥就像让View搬家动画怎么办?
很简单:ValueAnimator呗,在刷新时对layout进行更新
由于有四个setXXX方法,这里,简单一点,使用ObjectAnimator
![](https://img.haomeiwen.com/i15405328/ac451f1f2aef056d.png)
6:scrollTo和scrollBy
可以说这两个方法和上面的不是一辈的人,应用场景有很大区别
这两个方法是移动一个View内部的所有子View,调用方并非子View
至于To和By的区别,也是老生常谈,看图体悟吧...
scroll
ToscrollBy
Ok ,基础知识就到这里
最后附上小编整理出来的Android相关的学习思维导图,让大家有个学习的方向,早日拿到大厂的offer。
Android进阶
Android前沿技术
Flutter
移动架构师
需要这些安卓学习资料和面试资料的大伙需要的关注+点赞+加群:185873940 免费获取!
群内还有许多免费的关于高阶安卓学习资料,包括高级UI、性能优化、架构师课程、 NDK、混合式开发:ReactNative+Weex等多个Android技术知识的架构视频资料,还有职业生涯规划及面试指导。
网友评论