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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值