定制控件Custom Components

基于两个基础的类:View和ViewGroup,Android提供了一个精致而强大的组件化的用户界面。此前,Android平台预先提供了各种各样的View和ViewGroup的子类——被称作widgets和layouts。当然你也可以单独的构建你自己的ui。

可用的widgets包括  ButtonTextViewEditTextListView,CheckBoxRadioButtonGallerySpinner,还有基于特殊用途的AutoCompleteTextViewImageSwitcher, and TextSwitcher.

可用的layouts有 LinearLayoutFrameLayoutRelativeLayout, 等,更多例子请查看 Common Layout Objects.

如果系统预先提供的widgets和layouts不能满足你的需求,你可以创建你自己的View子类。如果你想对系统提供的widgets和layouts做修改,你可以继承它们并重载它们的方法。

如果创建自定义的View的子类,你可以精确的控制它的外观和功能。下面是你能对自定义控件做的控制:
1 你可以创建一个完全自定义渲染方式的控件,例如一个用2d图形渲染的把手,类似于模拟电子控制。

2你可以将多个view组合在一起,成为一个单独的组件。

3你可以重载EditText在屏幕上的渲染方式(Notepad Tutorial 通过这个方式来达到好的效果)

4你可以捕捉其他的事件,并用自定义的方式处理他们。

下面的部分解释如何创造自定义控件,并在app中使用他们:

The Basic Approach

这里是在创建自定义控件之前你需要知道的一个概述:
1用你自己的类继承一个现存的View或其子类。
2重载一些父类中的方法。父类中以on开头的方法如: onDraw() onMeasure() , and  onKeyDown() .这和 Activity or ListActivity 中的你复写on开头的方法一样。
3使用你自己的类,一旦上述步骤完成,你自定义的类就可以替代它所继承的View来使用。
tip:自定义的类可以作为要使用它们的Activity的内部类。这这很有用,因为控制了对他们的不必要的访问(当然你也许想创建一个新的公共类来在你的app中更广泛的应用)。

Fully Customized Components

完全自定义可以用来创建你所希望的以任何方式表现的绘图组件。无论什么方式,这是你用组合的控件怎么也做不到的。幸运的是,你可以创建具有任意外观和行为的控件,唯一的限制可能是你的想象力,屏幕的尺寸,处理器运算能力。
为了创建一个完全自定义的控件:
1继承最多的父类是View,所以你将经常从这里开始。
2可以增加一个构造器,它可以从xml文件中获取属性和参数,定义你自己的属性和参数(也许是颜色和宽度)
3可以在自定义的控件中创建你自己的事件监听器,属性访问器和修改器,和更复杂的行为
4重载onMeasure()方法。也很可能重载onDraw()方法,如果你要让控件显示什么的话。这两个函数都有默认的行为,onDraw()默认是什么都不做,onMeasure()方法将会设置100*100的尺寸(也许不是你要的)。
5根据需要重载其他on开头的方法

Extend onDraw() and onMeasure()

onDraw()方法传递一个   Canvas类 ,通过它你可以实现任何图形:2d图形,其他的标准或自定义的控件,文字字体等
注意:这不能表现3d图形,如果你想使用3d图形,你必须继承SurfaceView而不是View,并另一个线程中绘制。在GLSurfaceViewActivity sample中获取更多信息
onMeasure()会被更多的调用。onMeasure()是组件和容器之间渲染关系的重要部分。onMeasure()必须高效而精确的重写,以此反应组件的把尺寸。这稍微有点复杂,它是通过父类的限制要求(其传递给onMeasure()方法)和用测量的宽度和高度(一旦计算完成后)调用setMeasuredDimension()方法的要求。如果你在重载的onMeasure()方法中调用setMeasureDimension()方法失败,结果将是一个在测量时的异常。
实现onMeasure()方法,大概步骤如下:
1重载的onMeasure()方法的参数有宽度和高度的测量规格(分别是widthMeasureSpec和heightMeasureSpec参数,两个都是整数来代表维度),这两个参数是你测量产生的高度和宽度的限制性要求。更详细的关于测量的说明可以在View的onMeasure()方法说明中找到。
2你的控件的onMeasure方法应该计算它自身的高度和宽度,这将被用来渲染这个控件。测量的大小应该尽量在传进来的规格参数之内,当然你也可以选择超过规格要求(在这种情况下,父容器可以选择怎么做,包括抛出异常,滑动,剪掉或者要求onMeasure用不同的规格再次测量)。
3一旦高度和宽度被测量,setMeasureDimension(int width,int height)方法必须被调用(将测量的宽和高作为参数传进去)。若失败的话将会抛出异常。

下面是一些框架会调用的view的标准方法的总结:

Category Methods Description
Creation Constructors There is a form of the constructor that are called when the view is created from code and a form that is called when the view is inflated from a layout file. The second form should parse and apply any attributes defined in the layout file.
onFinishInflate() Called after a view and all of its children has been inflated from XML.
Layout onMeasure(int, int) Called to determine the size requirements for this view and all of its children.
onLayout(boolean, int, int, int, int)                                                                                                                           Called when this view should assign a size and position to all of its children.
onSizeChanged(int, int, int, int) Called when the size of this view has changed.
Drawing onDraw(Canvas) Called when the view should render its content.
Event processing onKeyDown(int, KeyEvent) Called when a new key event occurs.
onKeyUp(int, KeyEvent) Called when a key up event occurs.
onTrackballEvent(MotionEvent) Called when a trackball motion event occurs.
onTouchEvent(MotionEvent) Called when a touch screen motion event occurs.
Focus onFocusChanged(boolean, int, Rect) Called when the view gains or loses focus.
onWindowFocusChanged(boolean) Called when the window containing the view gains or loses focus.
Attaching                                                                                                                                                                                                                    onAttachedToWindow() Called when the view is attached to a window.
onDetachedFromWindow() Called when the view is detached from its window.
onWindowVisibilityChanged(int) Called when the visibility of the window containing the view has changed.

A Custom View Example

自定义控件的一个例子,在api demos中有提供。自定义的view在LabelView中被定义。
LabelView的例子展示了自定义控件的许多方面:
1继承View类。
2参数化的构造器来加载参数(定义在xml)。其中一些传递给view的子类,但更重要的是,有一些自动义的属性定义在labelView中。
3你希望在label控件中出现的标准public方法,如setText(),setTextSize(),setTextColor()等
4重载的onMeasure方法来决定和设置控件的渲染范围(注意在LabelView方法中,真正的工作室由private的measureWidth()方法做的)
5重载的onDraw方法来把文字写在提供的canvas上
你可以在一些例子中的custom_view_1.xml看到LabelView的使用。特别的,你可以看到android:开头的参数和自定义的app:开头的参数的混合使用。app:开头的参数是LabelView中的,它们是在R资源定义类的内部类styleable类中定义的。


你可能感兴趣的:(定制控件Custom Components)