Android自定义View之旅(一)自定义View的几种方式

通常,自定义View有三个大的区分点,在日常开发中遇到自定义View的需求时,最好想一想该走哪条路,走得快一些轻松些总是好的。

1 简单的“自定义”

需求总是在不经意间来临,也许是原生控件丑了点,也许是哪些布局复用的多了些,Leader让改改,写个自定义View解决一下,减少一下重复开发工作,这时候该我们迎难而上了,必要的时候还是得造个轮子。

这时候,看一眼需求,原来是这个TextView的样式太单调了,只有简单的背景、前景色之类的,产品和UI让改改加点炫酷的东西,文字得一上一下写()。得,自定义View吧,感觉相对于原生的TextView区别只有一个,绘制过程中调整一下位置即可,那就简单点,写个UpDownTextView,继承TextView,改改onDraw()方法。

第一个需求解决,来看下一个需求,咱们项目中有个布局好像用的比较多,好几个地方用到了,关键它逻辑也一样,只是include布局文件还是要写不少重复代码,得抽离一下。自定义View吧,看看已经抽离的布局文件,这个布局是一个RelativeLayout,里面包含了我们需要的控件之类的,写个BtRelativeLayout继承RelativeLayout,然后把布局文件的根布局RelativeLayout改成BtRelativeLayout,再把原有的逻辑都写在BtRelativeLayout类里,搞定。

简单的“自定义”就是这样了,继承了现成的控件,再在此基础上完成附加的功能样式或者更改原有的功能样式,可以迅速达到想要的效果,缺点是会受到父类的限制、无法完成复杂的需求。

2 重写一个View

万恶的需求又来了,抄家伙上!一顿操作猛如虎,一看需求心里堵。来吧,这会真的要重头写一个View了。

先仔细看看需求,一个声音波形控件,持续动画效果,单靠上面的简单实现是不可能的了,需要的效果如下:
在这里插入图片描述
这时候是时候新建一个类VoiceLineView,继承自View,我们来理一理大致思路:

  1. 可能需要我们重写onMeasure()方法,计算VoiceLineView的宽高。
    根据父布局传入的MeasureSpec,计算出自身的宽高并保存。
  2. 可能需要我们重写onDraw()方法,对VoiceLineView的绘制进行控制。
    循环绘制,根据宽高、每个点的位置绘制需要的波形图。
  3. 可能需要我们提供一些自定义的属性,方便上层定制化VoiceLineView
    提供样式、颜色、最大值等属性设置。

如果有感兴趣的小伙伴可以动手写了,具体的实现我将会放在下一篇文章当中,文章链接等我写完下一篇文章后会更新。

3 重写一个ViewGroup

VoiceLineView顺利上线使用,是时候放松一波了,掏出我新买的小梳子,打理一下为数不多的头发。很秃然,一只大手摸上了我的肩。。。一个抖激灵,一根珍贵的秀发开始了一场说走就走的旅行(T^T)。产品大叔又又又来了!!!

在无数次压下拔刀斩的念头之后,我们看看这次的需求,很好,改造图片九宫格的重任,根据图片的数量调整图片的布局(仿造Facebook ),让页面不要那么死板,是个鸡肋 不错的想法。

我们先来看看原有的图片九宫格,和微信的朋友圈图片九宫格一样,固定图片大小,最多是一个三行三列的表格,简单高效,多好的孩子,动什么刀子啊,ε=(´ο`*)))唉。

话说回来,要实现需求需要一个自定义的ViewGroup,就叫DynamicImageGroup吧,类似的,我们来理一理大致思路:

  1. 可能需要我们重写onMeasure()方法,计算DynamicImageGroup的宽高。
    根据父布局传入的MeasureSpec,计算出自身的宽高并保存。
  2. 可能需要我们重写onLayout()方法,计算子View的位置。
    根据onMeasure()方法中计算并保存的宽高、子View的宽高,计算子View的位置。
  3. 可能需要我们提供缓存机制,加快绘制速度减少卡顿。

如果有感兴趣的小伙伴可以动手写了,具体的实现我将会放在之后的文章当中,文章链接等我写完后会更新。

4 综述

三条路都有适用点,我们要合理选择,做最懒的程序猿:

  1. 站在巨人的肩膀上。对一些只是在某个View的基础上进行的改动,只需要直接继承该View,按需替换或者增删功能,最快速度完成需求。
  2. 必要的时候,轮子还是要造的。对于系统目前没有类似View的需求,如果不是包含某些View的话,实现类继承自View,重写onMeasure()方法和onDraw()方法,再提供自定义属性。
  3. 必要的时候,可能还得造个车。需要包含某些View的情况下,如没有类似的ViewGroup可以改改的话,就需要实现类继承自ViewGroup,重写onMeasure()方法和onLayout()方法,有需要的话可以加上缓存机制。

下一篇文章Android自定义View之旅(二)继承View实现自定义

posted @ 2020-11-11 19:54  coder-ice  阅读(667)  评论(0编辑  收藏  举报