当前位置: 代码迷 >> Android >> Android Developers:创办自定义视图类
  详细解决方案

Android Developers:创办自定义视图类

热度:29   发布时间:2016-04-28 07:40:56.0
Android Developers:创建自定义视图类

设计良好的自定义视图就像其它任何精心设计的类。它通过一个容易使用的接口封装了一个组特定的方法。它高效的使用CPU和内存,等等。除了是一个精心设计的类,然而,自定义视图应该: 

  • 遵守Android规范 

  • 提供在Android XML布局中工作的自定义属性。 

  • 发送可访问的事件。 

  • 兼容多个Android平台。 

 

Android框架提供了一组基本类和XML标签,来帮助你创建符合所有要求的视图。这节课程讨论如何使用Android框架来创建视图类的核心功能。 

 

子类化视图 

——————————————————————————————————————————————————————————————

在Android框架中被定义的所有视图类继承View。你的自定义视图也可以直接继承View,或者你能通过继承一个已经存在的视图子类来节省时间,例如Button。 

 

为了允许Android Developer Tool和你的视图交互,你必须至少提供一个构造方法,它使用Context和AttributeSet对象作为参数。这个构造方法允许布局编辑器来创造和编辑一个你的视图实例。 

class PieChart extends View {     public PieChart(Context context, AttributeSet attrs) {         super(context, attrs);     } } 


定义自定义属性 

——————————————————————————————————————————————————————————————

向你的用户界面添加一个内嵌的视图,你使用一个XML元素中指定它,并且使用元素属性控制它的显示和行为。完全自定义视图也能通过XML添加和样式化。为了在你的自定义视图中使用这种方式,你必须: 

  • 在<declare-styleable>资源元素中定义你的视图的自定义属性。 

  • 在你的XML布局中指定属性的值。 

  • 在运行时获取属性值。 

  • 将获取的属性值应用到你的视图中。 

 

这节讨论如何定义自定义属性和指定它们的值。下一节是关于在运行时获取和应用这些值。 

 

为定义自定义属性,向你的项目中添加<declare-styleable>资源,通常将这些资源放入/res/values/attrs.xml文件中。这里是attrs.xml文件的一个例子: 

<resources>    <declare-styleable name="PieChart">        <attr name="showText" format="boolean" />        <attr name="labelPosition" format="enum">            <enum name="left" value="0"/>            <enum name="right" value="1"/>        </attr>    </declare-styleable> </resources> 

这段代码声明两个自定义属性,shotText和labelPosition,它属于一个被命名为PieChart的可样式化实体。按照惯例,这个可样式化的实体的名字,和定义自定义视图类的名字相同。虽然不是非得遵守此约定,大多数程序员基于这种命名约定提供完整的描述。 

 

一旦你定义了自定义属性,你也能和内置属性一样,在XML布局文件中使用它们。唯一的不同是你的自定义属性属于一个不同的命名空间。代替属于http://schemas.android.com/apk/res/android命名空间,它们属于http://schemas.android.com/apk/res/android/[your package name],例如,这里演示了如何使用为PieChar定义的属性: 

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/com.example.customviews">  <com.example.customviews.charting.PieChart      custom:showText="true"      custom:labelPosition="left" /> </LinearLayout> 

为了避免重复长命名空间URI,这个例子使用xmlns指令。这个指令分配别名custom给http://schemas.android.com/apk/res/com.example.customviews命名空间。你可以使用任何你想分配给你的命名空间的别名。 

 

注意XML标识的名称将自定义视图添加到布局中,它是自定义视图类的完整描述名。如果你的视图类是一个内部类,你必须使用外部类的名称进一步限定它。例如PieChar类有一个被命名为PiaView的内部类。为了使用这个类的属性,你应该使用com.example.customviews.charting.PiaChar$PiaView标签。 

 

使用自定义属性 

——————————————————————————————————————

当一个视图在一个XML布局中被创建,在这个XML标签中的所有属性都从资源束中读取,并作一个AttributeSet被传递到这个视图的构造方法。虽然可以直接从AttributeSet中读取值,但是这样做有一些缺点: 

  • 在属性值内的资源引用没有被解析。 

  • 类型没有被应用。 

 

相反,传递AttributeSet给obtainStyledAttribute()方法,这个方法返回一个值数组TypedArray,它已经被引用和类型化。 

 

Android资源编译器为了你更方便的调用obtainStyledAttribute()方法,做了许多工作。对于在res目录下的每个<declare-styleable>资源,在生成的R.java文件定义了一个属性id数组和一个常量集合,它定义了在这个数组中的每个属性的索引。你使用这个预定义的常量来从TypedArray中读取对应属性。下面是PieChar类如何读取它的属性: 

public PieChart(Context context, AttributeSet attrs) {    super(context, attrs);    TypedArray a = context.getTheme().obtainStyledAttributes(         attrs,         R.styleable.PieChart,         0, 0);     try {        mShowText = a.getBoolean(R.styleable.PieChart_showText, false);        mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);    } finally {        a.recycle();    } } 

注意TypedArray对象是一个共享资源,并且在使用后必须被回收。 

 

添加属性和事件 

———————————————————————————————————————— 

属性是控制视图的行为和显示的一种强有力的方式,但是它们仅仅在视图被初始化的时候被读取。为了提供动态行为,为每个自定义属性提供属性的一对getter和setter方法。下面的代码段显示PieChart如何暴露被称为showText的属性。 

public boolean isShowText() {    return mShowText; }  public void setShowText(boolean showText) {    mShowText = showText;    invalidate();    requestLayout(); } 

注意setShowText调用invalidate()和requestLayout()。这些调用对于确保视图的行为可靠是至关重要的。在改变任何可能改它的显示的属性之后,你必须使视图无效,以至于系统知道它需要被重绘。另一方面,如果一个可能影响这个视图的大小或者形状的属性改变,你需要请求一个新的布局。忘记了调用这个方法会导致难以寻找的Bug。 

 

自定义视图也应该支持事件监听来沟通重要事件。例如,PieChar暴露一个被称为onCurrentItemChanged的自定义事件来通知来通知监听器,用户已经旋转了PieChar类聚焦一个新的Pie Slice。 

 

忘记暴露属性和事件是很容易的,尤其是当你这个自定义视图的唯一用户的时候。花一些事件细心定义你的视图界面来减少将来维护的开销。遵循好的做法就是,总是暴露任何影响你的自定义视图的外表和行为可见性的属性。 

 

可访问性设计 

———————————————————————————————————————— 

你的自定义视图应该支持最广泛的用户,这包括无法看见或使用触摸屏的残障用户。为了支持残障用户,你应该: 

  • 使用android:contentDescription属性标注你的输入框。 

  • 在适当的时候,通过调用setAccessibilityEvent()发送可访问事件。 

  • 支持备用控制器,例如D-pad和轨迹球。 

 

更多关于创建可访问视图的信息,查阅在Android Developers Guide中Making Application Accessible。 

  相关解决方案