Android提供了一个复杂和强大的组件化模型来构建您的用户界面,基于基本的布局类: View和ViewGroup 。 首先,该平台包含各种预构建的View和ViewGroup子类 - 分别称为小部件和布局,您可以使用它们来构建UI。
可用小部件的部分列表包括Button , TextView , EditText , ListView , CheckBox , RadioButton , Gallery , Spinner和更特殊用途的AutoCompleteTextView , ImageSwitcher和TextSwitcher 。
可用的布局包括LinearLayout , FrameLayout , RelativeLayout等等。 有关更多示例,请参阅常见布局对象 。
如果没有预置的小部件或布局满足您的需求,您可以创建自己的View子类。 如果您只需对现有的小部件或布局进行小的调整,则可以简单地对小部件或布局进行子类化并覆盖其方法。
创建您自己的View子类可以精确控制屏幕元素的外观和功能。 为了让您了解使用自定义视图获得的控制权,以下是您可以使用的一些示例:
您可以创建一个完全自定义渲染的视图类型,例如使用2D图形渲染的“音量控制”旋钮,类似于模拟电子控制。
您可以将一组视图组件组合到一个新的单个组件中,也许可以像ComboBox(弹出列表和自由输入文本字段的组合),双窗格选择器控件(带有列表的左窗格和右窗格在哪里你可以重新分配哪个项目在哪个列表中)等等。
您可以重写EditText组件在屏幕上呈现的方式( 记事本教程使用此效果,创建一个记事本页面)。
您可以捕获按键等其他事件,并以某种自定义的方式处理它们(例如游戏)。
下面的部分解释了如何创建自定义视图并在您的应用程序中使用它们。 有关详细的参考信息,请参阅View类。
基本方法
以下是开始创建自己的View组件所需知道的高级概述:
用你自己的类扩展现有的View类或子类。
覆盖超类的一些方法。 例如onDraw() , onMeasure()和onKeyDown() ,覆盖开头的超类方法。 这与Activity或ListActivity中的on...事件类似,可以覆盖生命周期和其他功能钩子。
使用你的新扩展类。 一旦完成,您的新扩展类可以用来代替它所基于的视图。
提示:扩展类可以在使用它们的活动中定义为内部类。 这是有用的,因为它控制对它们的访问,但不是必需的(也许你想创建一个新的公共视图,以便在你的应用程序中使用)。
完全定制的组件
完全自定义的组件可以用来创建出现的图形组件,但是你希望。 也许是一个图形化的VU表,看起来像一个古老的模拟仪表,或一个长长的文字视图,弹跳球沿着这个单词移动,所以你可以跟卡拉OK机一起唱歌。 无论哪种方式,无论您如何组合它们,都需要内置组件不会执行的操作。
幸运的是,您可以轻松创建以您喜欢的任何方式显示和行为的组件,可能仅受限于您的想象力,屏幕的大小以及可用的处理能力(请记住,最终,您的应用程序可能必须运行在显着减少比你的桌面工作站更强大)。
要创建一个完全定制的组件:
您可以扩展的最通用的视图,不出所料, View ,所以你通常会开始扩展这个来创建你的新的超级组件。
你可以提供一个可以从XML获取属性和参数的构造函数,也可以使用你自己的属性和参数(可能是VU表的颜色和范围,或者针的宽度和阻尼等等)
你可能想要创建你自己的事件监听器,属性访问器和修饰符,以及在你的组件类中可能更复杂的行为。
你几乎可以肯定想要重写onMeasure() ,如果你想让组件显示一些东西,也可能需要重写onDraw() 。 虽然两者都具有默认行为,但默认的onDraw()将不会执行任何操作,默认的onMeasure()将始终将大小设置为100x100,这可能不是您想要的。
其他on...方法也可以根据需要被覆盖。
扩展onDraw()和onMeasure()
onDraw()方法为您提供了一个Canvas ,您可以在其中实现任何您想要的内容:2D图形,其他标准或自定义组件,样式化文本或任何您能想到的东西。
注意:这不适用于3D图形。 如果要使用3D图形,则必须扩展SurfaceView而不是View,然后从单独的线程中绘制。 有关详细信息,请参阅GLSurfaceViewActivity示例。
onMeasure()有一点涉及。 onMeasure()是组件与其容器之间呈现协议的关键部分。 onMeasure()应该被覆盖,以有效和精确地报告其包含的部分的度量。 根据父级(传入onMeasure()方法)的限制要求以及要求在计算完成后调用带测量宽度和高度的setMeasuredDimension()方法的要求,稍微复杂一些。 如果您无法通过重写的onMeasure()方法调用此方法,则结果将在测量时间例外。
在高层次上,实现onMeasure()看起来像这样:
重写的onMeasure()方法被称为宽度和高度测量规范( widthMeasureSpec和heightMeasureSpec参数,两者都是表示尺寸的整数代码),应将其视为对您应该生成的宽度和高度测量的限制的要求。 在参考文档View.onMeasure(int, int) (参考文档对解释整个测量操作也做了很好的工作View.onMeasure(int, int)可以找到这些规范所要求的那些限制的完整参考。
你的组件的onMeasure()方法应该计算渲染组件所需的测量宽度和高度。 它应该尽量保持在规定的范围内,尽管它可以选择超过它们(在这种情况下,父母可以选择做什么,包括剪裁,滚动,抛出异常,或要求onMeasure()再试一次,也许具有不同的测量规格)。
计算宽度和高度后,必须使用计算的度量值调用setMeasuredDimension(int width, int height)方法。 不这样做将导致异常被抛出。
以下是框架调用视图的一些其他标准方法的摘要:
构造函数
当从代码创建视图时调用构造函数的一种形式,以及从布局文件膨胀视图时调用的形式。 第二种形式应解析和应用布局文件中定义的任何属性。