建立自定义view(翻译 androidtraining)

 

建立自定义view

一个设计良好的的自定义view应该是一个设计良好的class,它包含了不少实用的功能,让人们更加容易使用接口。它充分利用GPU与内存的性能等等。 另外做为一个设计良好的类,一个自定义view还应该有如下特性:html

  • 听从android标准java

  • 提供能够在layout中使用的自定义属性android

  • 兼顾各类人士需求(好比视力,听力)web

  • 兼容各类android平台版本数组

android的sdk提供了一系列的基础的类和xml的标记来帮助你建立一个知足你需求的自定义view。本节课将讨论如何利用android的framwork来建立一个有基本核心功能的自定义view。app

继承一个view


android系统framwork层的view都是继承自View这个基类。你的自定义view也能够直接继承自View,或者你为了节省时间能够继承一个已经存在的子类,好比Button。编辑器

为了让Android Developer Tools 能和你的自定义view交互,你必须最少提供一个接受Context和AttributeSet为参数的构造函数。经过这个构造函数,layout编辑器能够建立和编辑你的自定义view的实例。(也就是能够在未运行的时候,展现出界面)ide

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

定义自定义的属性

为了向你的界面中添加一个内建的view,你须要在xml元素里面指定,而后经过元素的属性控制它的显示和行为。为了作到这一点,你必须:函数

  • <declare-styleable>资源属性下为你的自定义view定义属性性能

  • 在xml layout中指定属性的值

  • 在运行的时候,接受属性的值

  • 将接受的值应用到你的view中去

这一节讨论了如何定义自定义的属性与指定他们的值。下一节将处理在运行时接收与应用属性的值。

为了定义自定义属性,添加<declare-styleable>资源到你的工程中。一般咱们会将这些资源放到res/values/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>

上面的代码声明了两个自定义属性,showtextlablePosition,这两个属性属于styleable 实体,命名为PieChart,styleable实体的命名一般为了方便,和你的自定义view的名字同样。尽管这不是一个严格的规定,可是不少很是流行的开源代码的做者也是听从这个原则。

一旦你定义了自定义属性,你就能够像内置的android属性那样来运用你的属性。惟一的不一样就是你的自定义属性是属于一个不一样的命名空间的。他们不是属于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>

为了不重复这么长的命名空间,上面的例子使用了一个xmlns指示符。这个指示符把custom这个名字赋值给了http://schemas.android.com/apk/res-auto这个命名空间。 你能够选择任何的同名简化单词来替代你的命名空间。

Note:若是你没有使用gradle来构建你的系统,你的xlmns URI不能包含 res-auto 。这个URI比较包含完整的你的项目的名字。这个例子中,若是不是grale构建的话,URI应该为http://schemas.android.com/apk/res/com.example.customviews

请注意你在xml中指定的你的自定义view的名字。这个名字必须是这个类完整的类路径。若是你的自定义view是一个inner class,你必须讲outer class的名字也加上。例如,这个PieChart类若是有一个inner class 叫PieView.为了使用这个自定义view的属性,你应该这样写你的tag com.example.customviews.charting.PieChart$PieView

属性值的应用

当一个view从xml layout中建立出来后,全部的在xml tag中的属性就会从resourse bundle中读取出来而且传递给view的构造函数的参数AttributeSet.尽管咱们能够直接从AttributeSet中读取属性值,可是这样作有一些缺点。

  • 资源的引用的属性值没有被分解出来

  • Styles没有被应用到属性值上

因而,咱们把AttrbuteSet传递给obtainStyledAttributes()这个函数。这个函数会返回一个TypedArray,这个一系列的值,通过了解引用,同时将主题样式应用到值上。

Android的资源编译器在你调用obtainStyledAttributes()以前,作了不少工做。遍历res目录中<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方法。

添加类属性与事件

xml的属性是一个很强大的控制view显示与行为的方式,可是它们却只能在view初始化的时候来读取。为了提供动态的行为,咱们能够为每个xml属性提供get与set方法。下面代码片断展现了如何向外部提供一个get与set接口:

public boolean isShowText() {
   return mShowText;
}

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

注意下,setShowText方法调用了invalidate()与requestLayout().这些调用很重要,是用来保证view的行为是可靠的。当你修改了一些可能影响view显示的属性时,你必须invalidate你的view,这样系统就能够知道这个view须要从新绘制。一样的,当你修改了一些影响view大小与形状的属性时,你必须调用requestLayout。忘记调用这个函数,可能到致使不少难以发现的bug。

自定义view也应该支持一些事件的监听。例如,PieChart向外提供一个叫作 OnCurrentItemChanged方法,来通知监听者用户已经旋转了pie chart。

咱们很容易就忘记向外提供属性与事件监听,尤为是当这个自定义view只有咱们一我的使用的时候。花一些时间来定义这些view的接口,这样能够节省之后维护的成本花费。一个好的作法就是,将全部影响显示与行为的属性都向外提供接口。

定义可接受性

你的自定义view应该尽量支持更多的用户。包括视力,或者行动不方便的人士。为了支持这些人,你应该:

  • 在你的输入性的控件上面使用 android:contentDescription这个属性

  • 在合适的时间经过调用sendAccessiblityEvent发送兼容性事件

  • 支持交叉输入控制,好比轨迹球,D-pad

更多的关于建立兼容view的知识,请查看 Making Application Accessible

相关文章
相关标签/搜索