这一段时间写了不少自定义View,总算对自定义View有了一个大体上的理解,根据自己的理解自定义View其实总体分为三类。
1.自绘组件
2.组合组件
3.继承组件
网上的自定义View统称的方式就是那些固定的onMeasure,onDraw……,其实不仅仅如此,自定义View有很多可以利用的地方,通过我自己的体会,我感觉总体分为以上的三种比较合理,分别的实现方式也不同。
1.自绘组件
这算是我们想到自定义组件最先想到的一种,这种自定义View的难点在于几个点:
难点:
1.onMeasure中对于组件的测量,注意绘制的原点,注意MeasureSpec的三种测量模式,注意支持warp_content
2.onDraw中对于组件的绘制,怎么绘制,绘制什么,从哪绘制到哪结束,主要是对于Paint,cancas的掌握和对于View的几个坐标系数的掌握。
3.对于一些数学计算原理的学习,这里面经常要用到三角函数等数学公式,难一点的像贝塞尔曲线。
4.怎么绘制出来想要的东西,比如要想要个人的组件,肯定是先画头,再画身子,再画脚。
使用情景:
Android原生中没有相似的组件存在,经常一些炫酷的组件就是通过这种方式绘制出来的。
实现步骤:
1.在style文件中定义相关的属性(此项不是必须)
2.在构造函数函数中通过TypedArray获得刚才定义的属性,注意回收(也不是必须,这个只有上面定义了才做)
3.重写onMeasure,区分三种MeasureSpec测量模式(也不是必须,如果你这个自定义View这是画画玩)
4.重写onDraw方法,利用canvas和paint按照思路绘制
参考实例:
2.组合组件
这应该算是自定义组件中最简单的一种了,其实就是将常用的一个layout封装成一个View,方便复用。
难点:
1.接口回调,理解接口回调的方式
2.高内聚,低耦合,主要是组件的复用,不要让View和业务逻辑掺杂在一起。
使用场景:
主要是用于组件复用,比如经常写TitleLayout,完全可以封装成一个CommonTitle组件,不用每次都写进去一大堆重复的代码。
实现步骤:
1.在style文件中定义相关的属性(此项不是必须)
2.在构造函数函数中通过TypedArray获得刚才定义的属性,注意回收(也不是必须,这个只有上面定义了才做)
3.通过LayoutInflater加载xml文件或者通过addView的方式动态的添加组件。
4.封装相应的对外方法,对外接口。
参考实例:
ToTopView
CommonTitle
3.继承组件
这个是通过继承Android原生的已有的组件,通过改变和添加一些方法来说实现我们想要的效果。
难点:
1.对于所继承的组件的理解,要改变一个组件,肯定要理解这个组件的实现方式。
2.对View的生命周期的理解,在这种组件里经常需要用到View的Width和Height,但是经常出现为0的情况,这多数是以为此时View还没有执行onLayout方法,所以为0,要理解View的生命周期和Activity的生命周期的关系。
3.对组件源码的阅读,主要是理解组件的方法的用处。
使用场景:
对于一些和原生的组件很相近,但是又和自己的需求差一点的情况,这时就需要重写这个组件,根据自己的需求进行改写。
实现步骤:
1.extends * 继承相应组件
2.根据需求重写对应的方法。
参考实例:
竖向Viewpager(3D翻动效果画廊)
AutoFitTextView-根据文本内容自动调整字体大小的TextView
总结:
以上就是我现在对于自定义View的理解,我经过对自定义View在尝试过以上三种实现方式后,给我的感觉总的来说
难点:
1.如何实现?也就是idea,你拿到一个效果,要仔细分析这个效果的实现过程,将过程转变为可以用代码实现的过程,当完成这一步后,自定义View已经实现了一半,接下来就是将这个过程用代码码出来。
进阶:
1.如何封装?这个就联系到设计模式和设计思想了,可以多看看别人开源效果的源码(经典的,封装很好的),多看看Android原生的组件的源码(为什么一个TextView可以有1w+的代码,为什么要使用ListView+adapter,为什么要用Builder,为什么会有Helper等等等等),考虑到上面的问题后,就考虑考虑自己写的组件别人是否可以拿去直接用,自己的组件是否可以用adapter模式,builder模式等
2.考虑把自己的View发布出去吧!JitPack,