Android自定义view之ToggleButton

这是我第一次写有关于自定义view的博客,虽然很久之前照着慕课网的视频自己敲过一个Topbar,不过那个时候刚刚接触android,对于自定义view对的概念并不是非常清晰,现在有了比较全面的认识,再来写就感觉不一样了。

自定义View的种类

自定义view根据自定义程度大题可以分成3类。

  1. 组合已有的组件
  2. 继承已有的组件(功能扩展)
  3. 完全自定义(继承View或ViewGroup)

今天主要回顾一下完全自定义View的方法,这个比较有节奏感,另外两项比较混杂,要针对具体的情况具体分析。这里就以自定义一个开关按钮为例大致讲解一下。

完全自定义View的一般流程

  1. 新建类继承View
  2. 根据使用需求建立构造方法
    构造中需要完成的事项:
    • Paint实例化(绘制UI用到)
    • 在布局文件中加入带有完整包名的组件,并在根布局里申明自定义属性集合:http://schemas.android.com/apk/res-auto
    • 设置UI资源(在 Values 目录下新建 attrs 资源文件,通过 declare-styleable 定义必要的自定义属性,而后通过 getAttributeResourceValue 拿到资源对象)
  3. 重写 onMeasure 方法
    这里需要根据获得的资源重新设定组件的宽高
  4. 重写 onDraw(Canvas canvas)
    • 结合这里传入的 canvas 和构造中实例的 paint,以及获得的资源对象,就可以绘制对应的 view
    • 根据用户的点击或者触摸状态绘制合适的 View
  5. 新建监听接口,加入合适的方法
  6. 重写 onTouchEvent,监听触摸事件,响应用户操作
    • 根据用户触摸的动作更新必要的状态
    • 根据状态动作通过接口回传状态信息
    • 调用 invalidate()重新绘制,为用户操作提供反馈
    • return true 消费该触摸动作
  7. 建立必要的公有set,get方法
    • setSwitchBackgroundResource
    • setSlideButtonResource
    • setSwitchState
  8. 在布局文件里通过自定义属性设置资源
  9. 在UI界面里实例化该View,并设置监听接口

ToggleButton的源码

源码可以在这里看到:github.com/AlphaGao1993

一些问题

  1. 在xml引用自定义View的时候,其组件名必须为完整的包名;
  2. xml中在根布局里申明自定义属性命名空间时,AndroidStudio 只需要打出自定义的属性,就会自动在根布局中添加申明,并且默认为:
    xmlns:app=”http://schemas.android.com/apk/res-auto",
    而在Eclipse中就可以自己定义,因此在构造方法中就要注意命名空间的对应的问题了,如果不一致会导致无法取得资源对象,而报空指针异常
  3. 一些细节问题需要巧妙的计算,例如使滑块跟随手指的移动并且不会移除规定的范围