zoukankan      html  css  js  c++  java
  • 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实现自定义

  • 相关阅读:
    219. Contains Duplicate II
    189. Rotate Array
    169. Majority Element
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    119. Pascal's Triangle II
    118. Pascal's Triangle
    88. Merge Sorted Array
    53. Maximum Subarray
    CodeForces 359D Pair of Numbers (暴力)
  • 原文地址:https://www.cnblogs.com/hwb04160011/p/13960612.html
Copyright © 2011-2022 走看看