【Android Trainning 翻译】创建自定义View之创建一个自定义View类

原文地址http://developer.android.com/training/custom-views/create-view.html

说在前面的话:第一次翻译,自知翻译得不是很好,所以请读者(如果有读者的话)不要责怪,我相信以后会做得更好的。

为什么我要去翻译,我想原因有以下几点吧:

  1. 锻炼我的英语阅读的能力
  2. 通过认真地翻译,让我可以对翻译的内容有更深入的了解,可以很好的学习其中的知识。
  3. 将英文翻译为中文,可以帮助其他一些英语阅读有困难的人来学习文中的知识(当然了,我现在能力有限委屈,翻译的东西都是很简单的,但我希望以后能翻译一些很好的文中)

创建一个View类

一个设计良好的自定义View就像其它任何精心设计的类一样。它封装了一组特定的功能,并且有一个容易使用的界面,它还能有效地使用CPU和内存等等。尽管如此,除了是一个设计精心的类之外,一个自定义的view还应该
  • 符合Android标准
  • 提供可以在Android XML布局中使用的自定义属性
  • 发送可访问的事件(这个翻译得不是很好,纠结中抓狂。。。
  • 能够兼容多个Android平台
Android框架提供了一组基类和XML 标签来帮助你创建一个可以满足所有这些要求的自定义view。这节课讨论的如何使用Android框架来创建一个自定义view的核心功能。

继承一个View

Android框架中定义的所有视图类都是继承View类的。你的自定义view也可以直接的继承View类,或者你可以通过继承一个已经存在的View的子类比如Button类来节省时间。为了允许Android Developer Tools 与你的view相互配合,你至少提供一个含有一个Context对象和一个AttributeSet对象为参数的构造方法。这个构造方法允许布局编辑器来创建和编辑一个你的视图的实例。

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

定义自定义属性

为了添加一个内置的View到你的用户界面,你要指定一个XML元素和控制其外貌和行为的元素属性。精心编写的自定义视图也可以通过xml来添加和设置样式。为了让你的自定义视图能够有这个效果,你必须做到:
  • 在一个<declare-styleable>资源元素中为你的视图自定义属性
  • 在xml布局中制定属性的值
  • 在运行的时候获取属性的值
  • 使用获取到的属性值

这一节将讨论如何定义属性和为它们指定属性值。下一节将说明在运行的时候处获取和应用这些属性值。

要定义自定义的属性,需要添加 <declare-styleable>资源到你的项目中。习惯性的将这些<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>

以上代码声明了两个自定义属性,即 showText labelPosition,这两个属性都属于一个名叫PieChart的styleable 实体。按照惯例,这个styleable实体的名字应和自定义view类的类名一样。尽管这不是严格要求你必须要遵循这个惯例,但是许多流行的代买编辑器都依靠这种命名约定来提供代码提示。

一旦你自定义的属性,你就可以像内置的属性一样在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  ,你可以为你的命名空间取任意的别名。

注意将自定义view添加到layout布局中的xml 标签的名字,它是完全限定自定义view类的名字的。如果你的view类是一个内部类,你需要通过视图的外部类的名字来进一步限定。进一步,例如,这个 PieChart 类有一个内部类 PieView,为了使用自定义属性,你应该使用标签  com.example.customviews.charting.PieChart$PieView

应用自定义的属性


当一个视图由一个XML布局创建的时候,XML标签中的所有属性都从资源束中读取,并且作为一个 AttributeSet对象传递到视图类的构造方法中。虽然可以直接从AttributeSet对象中读取value值,但是那样做有一些缺点:
  • 属性值的资源引用还没有解决
  • 样式没有被应用
可以将 AttributeSet 传递给 obtainStyledAttributes() 来代替,这个方法返回一个已经被引用和添加样式的 TypedArray  数组值。

Android资源编译器为你做了许多事情来让你更容易的调用 obtainStyledAttributes() 。对于每一个<declare-styleable>资源,在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    对象是一个共享的资源,用完之后要回收(recycle)

添加属性和事件

属性是一种很有力的控制view的行为和界面的方法,但是它们只能在view初始化时被读取。为了提供动态的行为,需要显示的提供每一个自定义属性的getter 和 setter方法。下面的代码片段展示了 PieChart如何暴露 showText的属性:

public boolean isShowText() {
   return mShowText;
}

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

注意在 setShowText中调用了 invalidate() 和 requestLayout() 方法,这些调用时至关重要的,用来确保view的行为可靠。在任何可能改变视图外观的属性发送改变之后,你必须invalidate 视图,以至于让系统知道它需要重新绘制,同样的,如果一个可能影响视图的大小或者形状的属性改变了,你就需要请求一个新的layout。忘记了这两个方法的调用,会引起一些难以查找的bug。

自定义view也应该支持事件监听来传达重要的事件。例如,PieChart提供了一个叫  OnCurrentItemChanged的自定义的事件来通知监听者用户已经旋转了饼图从而专注于新的饼图。

很容易忘记提供属性和事件,特别是当你只是使用自定义view时。请花一些时间来仔细的定义你的接口来减少以后维护的开销。一个好的可以遵循的规则是总是提供可以影响自定义视图的形状或者行为的特性。

为体验设计

你自定义的view应该可以支持大范围的用户,这些用户包括那些看不见或者无法触摸的残疾人。为了支持这些残疾用户,你应该:
  • android:contentDescription 属性标注你的输入框
  • 在适当的时候通过调用 sendAccessibilityEvent() 方法来发送可访问的事件
  • 支持备用控制器,比如 D-pad 和 trackball

更多关于创建可访问的视图的信息,你查阅Android Developer Guide中的   Making Applications Accessible 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值