个人的习惯了,无所谓什么东西,先看官方的东西,再去自我发展和超越,就像常常有人问我学 .Net 看什么书比较好,我总是回答“MSDN”(个人做 .Net 还比较久了,任何文档都没有 MSDN 的好。真心喜欢,谁让人家有中文呢~~~)。
好吧,不多说。这一章就直接做成 Creating Custom Views 的汉化版了,就算是汉化原创吧 ~~
官方示例下载:CustomView.zip
Android 框架中包含了很多视图类,用于与用户交互和显示各种类型的数据集。但有时您的应用程序有一些内建的视图不能满足的独特需求。本单元演示如何创建您自己的具有健壮性和可重用性的视图。
一个精心设计的自定义视图非常类似于任何其他设计良好的类。它封装一组特定的功能,具有易于使用的界面,有效率的使用 CPU 和内存,依此类推。自定义视图还应:
Android 框架提供了一套基本类和 XML 标记,以帮助您创建一个视图,满足所有这些要求。本课将讨论如何使用 Android 框架来创建视图类的核心功能。
所有在 Android 框架中定义的视图都最终继承 View。您的自定义视图同样可以直接继承 View,或可以通过继承一个现有视图的子类,例如 Button 来节省时间。
要允许 Android 开发工具与您的视图进行最低限度的交互,您必须提供包括 Context 与 AttributeSet 参数的构造函数。此构造函数允许布局编辑器来创建与编辑您的视图实例。
class PieChart extends View {<span style="color: #0000ff">public</span> PieChart(Context context, AttributeSet attrs) { <span style="color: #0000ff">super</span>(context, attrs); }
}
向用户界面添加内建视图时,您通过 XML 元素指定它,并使用元素参数来控制其外观和行为。一个设计良好的自定义视图同样支持通过 XML 样式添加。要为您的自定义视图支持此行为,您必须:
本节讨论如何定义自定义参数和指定其值。下一节处理在运行时检索和应用的值。
若要定义自定义参数,请将 资源添加到项目中。通常将这些资源放入 res/values/attrs.xml 文件。如下是一个 attr.xml 文件示例:
PieChart"> showText" format=" boolean" /> labelPosition" format=" enum"> left" value=" 0"/> right" value=" 1"/>
这段代码在 PieChart 声明实体下定义了两个自定义参数,showText 与 labelPosition 。声明实体的名称一般应与其对应的自定义视图的名称相同。虽然不是必需的,但在许多代码编辑器中可能通过此名称提供自动完成特性。
完成自定义参数之后,您就可以在 XML 布局文件中像内建的参数那样使用它们。唯一的不同就是这些自定义参数属于不同的名称空间。而不是在 http://schemas.android.com/apk/res/android 中。新的名称空间样式为 http://schemas.android.com/apk/res/[your package name] 。如下是使用 PieChart 自定义参数的示例:
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 标记的名称。它是自定义视图类的完全限定的名称。如果您的视图类是一个内部类,必须进一步限定与视图的外部类的名称。进一步。例如,PieChart 类有一个称为 PieView 的内部类。若要使用此类中的自定义参数,将使用标记 com.example.customviews.charting.PieChart$PieView。
当从 XML 布局创建一个视图时,所有的 XML 标记中的参数是从资源包中读取和传递到视图的构造函数中的 AttributeSet。虽然它也可以直接从 AttributeSet 中读取值,但这样做所以具有一些缺点:
相反,使用 AttributeSet 的 obtainStyledAttributes()。此方法返回传递 TypedArray 数组,已经解析引用和样式的值。
Android 资源编译器做大量的工作让你轻松调用 obtainStyledAttributes()。每个资源 res 目录中生成 R.java 定义参数 id 数组和一组每个参数的数组索引常量。您可以使用预定义的常量从 TypedArray 读取该参数。下面是 PieChart 如何读取参数的示例:
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。
自定义视图也应支持沟通重要事件的事件侦听器。例如 PieChart 公开一个名为 OnCurrentItemChanged 的事件通知用户已旋转饼图,激活新的饼图扇区。
很容易忘记要公开的属性和事件,尤其是当你的自定义视图的唯一用户。花一些时间来仔细定义您的视图界面减少了日后的维修费用。一个好的规则是总是公开任何可能影响自定义视图可见外观或行为的属性。
您的自定义视图应支持最广泛的用户。若要支持残障用户,您应该:
有关创建可访问的视图的详细信息,请参阅 Android 开发人员指南中的使应用程序可以访问。