LinearLayout线性布局
FrameLayout层叠布局
GridLayout 格子布局
TableLayout 表格布局
AbsoluteLayout绝对布局
RelativeLayout 相对布局
l 实例代码片段(见布局文件)
<?xml version="1.0" encoding="utf-8"?> <!-- LinearLayout - 线形布局。 orientation - 容器内元素的排列方式。vertical: 子元素们垂直排列;horizontal: 子元素们水平排列 gravity - 内容的排列形式。常用的有 top, bottom, left, right, center 等,详见文档 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="right" android:orientation="vertical" > <!-- FrameLayout - 层叠式布局。以左上角为起点,将 FrameLayout 内的元素一层覆盖一层地显示 --> <FrameLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="FrameLayout" > </TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Frame Layout" > </TextView> </FrameLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello" /> <!-- GridLayout 格子布局。控件从左到右,从上至下进行布局 columnCount指定列数,rowCount指定行数 layout_gravity实现控件补齐或者充满 layout_row及layout_column指定显示的行或者列 控件间距margine的设置:leftMargin、topMargine、rightMargine、bottomMargin、useDefaultMargine --> <GridLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:columnCount="5" android:rowCount="4" android:useDefaultMargins="true" > <TextView android:layout_gravity="fill_horizontal" android:text="1.1" /> <TextView android:text="1.2" /> <TextView android:text="1.3" /> <TextView android:text="1.4" /> <TextView android:text="1.5" /> <TextView android:text="2.1" /> <TextView android:text="2.2" /> <TextView android:text="2.3" /> <TextView android:text="2.4" /> <TextView android:text="2.5" /> <TextView android:text="3.1" /> <TextView android:text="3.2" /> <TextView android:text="3.3" /> <TextView android:text="3.4" /> <TextView android:text="3.5" /> <TextView android:text="4.1" /> <TextView android:text="4.2" /> <TextView android:text="4.3" /> <TextView android:text="4.4" /> <TextView android:text="4.5" /> </GridLayout> <!-- TableLayout - 表格式布局。 TableRow - 表格内的行,行内每一个元素算作一列 collapseColumns - 设置 TableLayout 内的 TableRow 中需要隐藏的列的列索引,多个用“,”隔开 stretchColumns - 设置 TableLayout 内的 TableRow 中需要拉伸(该列会拉伸到所有可用空间)的列的列索引,多个用“,”隔开 shrinkColumns - 设置 TableLayout 内的 TableRow 中需要收缩(为了使其他列不会被挤到屏幕外,此列会自动收缩)的列的列索引,多个用“,”隔开 --> <TableLayout android:id="@+id/TableLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:collapseColumns="1" > <TableRow android:id="@+id/TableRow01" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="行1列1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="行1列2" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="行1列3" /> </TableRow> <TableRow android:id="@+id/TableRow01" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="行2列1" /> </TableRow> </TableLayout> <!-- AbsoluteLayout - 绝对定位布局。 layout_x - x 坐标。以左上角为顶点 layout_y - y 坐标。以左上角为顶点 --> <AbsoluteLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="100px" android:layout_y="100px" android:text="AbsoluteLayout" /> </AbsoluteLayout> <!-- RelativeLayout - 相对定位布局。 layout_centerInParent - 将当前元素放置到其容器内的水平方向和垂直方向的中央位置(类似的属性有 :layout_centerHorizontal, layout_alignParentLeft 等) layout_marginLeft - 设置当前元素相对于其容器的左侧边缘的距离 layout_below - 放置当前元素到指定的元素的下面 layout_alignRight - 当前元素与指定的元素右对齐 --> <RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/abc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="centerInParent=true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20px" android:text="marginLeft=20px" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@id/abc" android:layout_below="@id/abc" android:text="xxx" /> </RelativeLayout> </LinearLayout>
l 综述
线性布局。布局内各控件元素成线性排列
层叠布局。故名思意,布局内各个控件叠加在一起
格子布局。4.0新增布局。控件从做到右,从上到下排列
表格布局。通过行列来格式化布局内的控件
绝对布局。以点(pX,pY)来控制控件的绝对位置
相对布局。以其他控件作为参照物的布局模式
l UML显示继承关系
l View 类(译自android-sdk/docs/reference/android/view/View.html)
View类是界面组件中的基础,是所有Widget的基类,如UI交互控件:按钮控件、文本控件等等。每个View占用一块矩形大小的区域并对绘制和事件处理做出相应的响应。值得关注的是,View类的子类ViewGroup,是各种布局类的基类。
Using Views
All of the views in a window are arranged in a single tree.You can add views either from code or by specifying atree of views in one or more XML layout files. There are many specializedsubclasses of views that act as controls or are capable of displaying text,images, or other content.
Once you have created a tree of views, there are typicallya few types of common operations you may wish to perform:
窗口中所有的Views是以单个树形结构来组织的。你可以通过代码或者通过一个或多个XML布局文件指明一个Views树来增加Views。Views有很多特殊的子类,有的用于controls,有的适于显示文本、图像或者其他的内容。
一旦你创建了一个View树,这有一些常见的操作需要执行:
Setproperties: forexample setting the text of a TextView. The available properties and themethods that set them will vary among the different subclasses of views. Notethat properties that are known at build time can be set in the XML layoutfiles.
设置各种属性:比如设置TextView控件的文本。Views中提供的属性和设置属性的方法因子类的不同而多样化。需要注意的是,这些属性同样可以在XML布局文件中设置。
Setfocus: Theframework will handled moving focus in response to user input. To force focusto a specific view, call requestFocus().
设置焦点:框架将会处理用户输入中的焦点转移。某个View强制获取焦点,需要调用requestFocus()方法。
Setup listeners: Viewsallow clients to set listeners that will be notified when something interestinghappens to the view. For example, all views will let you set a listener to benotified when the view gains or loses focus. You can register such a listenerusing setOnFocusChangeListener(android.view.View.OnFocusChangeListener). Otherview subclasses offer more specialized listeners. For example, a Button exposesa listener to notify clients when the button is clicked.
设置各种监听事件:可以对View设置监听,对于这些Views,当有些感兴趣的事情发生时,监听器负责告之这些Views。比如,所有的Views需要你设置监听来通知获得和失去焦点事件。一些子类提供更多特殊的监听器。比如,Button控件的点击事件的监听。
Setvisibility: Youcan hide or show views using setVisibility(int).
设置可见性:你可以调用setVisibility(int)方法来隐藏或是显示Views.
Implementing a Custom View
To implement a custom view, you will usually begin byproviding overrides for some of the standard methods that the framework callson all views. You do not need to override all of these methods. In fact, youcan start by just overriding onDraw(android.graphics.Canvas).
为了实现自定义的View,你通常从覆盖Views中的一些标准的方法开始。你不需要覆盖所有方法。事实上,你可以仅仅从覆盖onDraw()方法开始。
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(android.graphics.Canvas) |
Called when the view should render its content. |
Event processing |
onKeyDown(int, KeyEvent) |
Called when a new hardware key event occurs. |
onKeyUp(int, KeyEvent) |
Called when a hardware 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, android.graphics.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. |
解读:onMeasure(inr,int)是对view及其所有子view的测量。onLayout(boolean,int,int,int,int)是分配子view的size和location。onDraw(canvas)是渲染本view的内容
IDs
每个View拥有唯一的ID进行关联,这在初始化的时候有助于找到它。如下面代码片段:
<Button
android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_button_text"/>
Button myButton = (Button) findViewById(R.id.my_button);
Position
The geometry of a view is that of a rectangle. A view has alocation, expressed as a pair of left and top coordinates, and two dimensions,expressed as a width and a height. The unit for location and dimensions is thepixel.
一个view的几何图形是一个矩形。每个view拥有一个location和两个dimengsions(width,height)。location由一对坐标表示(left,top),dimensions由width和height表示。location和 dimensions的单位是px。
It is possible to retrieve the location of a view byinvoking the methods getLeft() and getTop(). The former returns the left, or X,coordinate of the rectangle representing the view. The latter returns the top,or Y, coordinate of the rectangle representing the view. These methods bothreturn the location of the view relative to its parent. For instance, whengetLeft() returns 20, that means the view is located 20 pixels to the right ofthe left edge of its direct parent.
可以调用getLeft()和getTop()方法来获取view的location。前者返回该view矩形区域的left,或者说是坐标点的X。后者返回该View矩形区域的top属性,或者说是坐标点的Y。这些方法都返回相对于其父view的location。比如,当getLeft()返回20,这意味着该view距离其父view左边边界20px。
In addition, several convenience methods are offered toavoid unnecessary computations, namely getRight() and getBottom(). Thesemethods return the coordinates of the right and bottom edges of the rectanglerepresenting the view. For instance, calling getRight() is similar to thefollowing computation: getLeft() + getWidth() (see Size for more informationabout the width.)
另外,提供一些便利的方法getRight()和getBottom(),以此来避免一些不必要的计算。这些方法返回代表view的矩形的右边和底边的坐标值。例如,调用getRight()方法和下面的计算产生一样的效果:getLeft()+getWidth().
总结如下:
getLeft()。得到View的起始坐标点X
getTop()。得到View的起始坐标点Y
getRight()。等价于getLeft()+getWidth()
getBottom()。等价于getTop()+getHeight()
Size,padding and margins
The size of a view is expressed with a width and a height.A view actually possess two pairs of width and height values.
View的大小由width和height两个属性表示。实际上,每个view都有两对width和height值。
The first pair is known as measured width and measuredheight. These dimensions define how big a view wants to be within its parent(see Layout for more details.) The measured dimensions can be obtained bycalling getMeasuredWidth() and getMeasuredHeight().
第一对是measured width 和 measured height。
The second pair is simply known as width and height, orsometimes drawing width and drawing height. These dimensions define the actualsize of the view on screen, at drawing time and after layout. These values may,but do not have to, be different from the measured width and height. The widthand height can be obtained by calling getWidth() and getHeight().
第二对是width和height,是绘制时的宽和高。这两个长度是布局完成之后屏幕上显示的实际的长度。这些长度值,可能但是没有必要与measured width和measured height不同。通过调用getWidth()和getHeight()函数获得width和height值。
To measure its dimensions, a view takes into account itspadding. The padding is expressed in pixels for the left, top, right and bottomparts of the view. Padding can be used to offset the content of the view by aspecific amount of pixels. For instance, a left padding of 2 will push theview's content by 2 pixels to the right of the left edge. Padding can be setusing the setPadding(int, int, int, int) method and queried by callinggetPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom().
为了测量dimensions,view的padding应该考虑进去。Padding是由view的四个边界部分定义的:left、top、right、bottom。Padding用来通过指明一定像素大小让content产生偏移。例如,一个left padding值为2像素的view所显示的content将会被推移到距离view左边2个像素长的位置。可以通过调用setPadding(int,int,int,int)方法来设置padding属性,查询相应的值调用getPaddingLeft(),getPaddingTop(),getPaddingRight(),getPaddingBottom()。
Even though a view can define a padding, it does notprovide any support for margins. However, view groups provide such a support.Refer to ViewGroup and ViewGroup.MarginLayoutParams for further information.
虽然view能够定义padding,但是对margines没有提供任何支持。不过,viewGroup这个类提供了相应的支持。
Layout
Layout is a two pass process: a measure pass and a layoutpass. The measuring pass is implemented in measure(int, int) and is a top-downtraversal of the view tree. Each viewpushes dimensionspecifications down the tree during the recursion. At the end of themeasure pass, every view has stored its measurements. The second pass happensin layout(int, int, int, int) and is also top-down. During this pass eachparent is responsible for positioning all of its children using the sizescomputed in the measure pass.
Layout分割为两个过程:测量过程和布局过程。测量过程由mesaure(int,int)实现,并且自上而下遍历整个view树。每个view通过递归的方式深入到整个view树中,在测量过程的最后阶段,每一个view都存储了各自的尺寸。第二个过程在layout(int,int,int,int)函数被调用时发生,并且也是自上而下的方式。在这个过程中,每个父view利用第一个过程中计算的view尺寸来对其所有孩子view进行布局。
When a view's measure() method returns, itsgetMeasuredWidth() and getMeasuredHeight() values must be set, along with thosefor all of that view's descendants. A view's measured width and measured heightvalues must respect the constraints imposed by the view's parents. Thisguarantees that at the end of the measure pass, all parents accept all of theirchildren's measurements. A parent view may call measure() more than once on itschildren. For example, the parent may measure each child once with unspecifieddimensions to find out how big they want to be, then call measure() on themagain with actual numbers if the sum of all the children's unconstrained sizesis too big or too small.
当view的measure()方法返回时,getMeasuredWidth()和getMeasuredHeight()方法返回的值将要被设置。view测量的width和height值必须遵循于其父view限定的值。这样保证了在测量过程结束时,所有的父view都能满足其子view的尺寸。父view调用measure()方法的次数可能比其子view所调用的多一次。例如,父view首先会测量其每一个子view所需要的大小,然后再调用一次measure()以求证所有的子view尺寸的总和是否太大或太小。
The measure pass uses two classes to communicatedimensions. The View.MeasureSpec class is used by views to tell their parentshow they want to be measured and positioned. The base LayoutParams class justdescribes how big the view wants to be for both width and height. For eachdimension, it can specify one of:
测量过程利用两个类来与dimensions通信。View.MeasureSpect类用来通知其父view需要怎么样测量和布局。LayoutParam基类则描述了view本身需要的width值和height值。
an exact number
MATCH_PARENT, which means the view wants to be as big asits parent (minus padding)
WRAP_CONTENT, which means that the view wants to be justbig enough to enclose its content (plus padding).
There are subclasses of LayoutParams for differentsubclasses of ViewGroup. For example, AbsoluteLayout has its own subclass ofLayoutParams which adds an X and Y value.
MeasureSpecs are used to push requirements down the treefrom parent to child. A MeasureSpec can be in one of three modes:
对于不同ViewGroup的子类,LayoutParams也有相应的子类。例如,绝对布局拥有的LayoutParams的子类能够添加X值和Y值。MeasureSpec可以是一下三种模式中的一种:
UNSPECIFIED:This is used by a parent to determine the desired dimension of a child view.For example, a LinearLayout may call measure() on its child with the height setto UNSPECIFIED and a width of EXACTLY 240 to find out how tall the child viewwants to be given a width of 240 pixels.
EXACTLY:This is used by the parent to impose an exact size on the child. The child mustuse this size, and guarantee that all of its descendants will fit within thissize.
AT_MOST:This is used by the parent to impose a maximum size on the child. The childmust gurantee that it and all of its descendants will fit within this size.
To intiate a layout, call requestLayout(). This method istypically called by a view on itself when it believes that is can no longer fitwithin its current bounds.
初始化一个布局,调用requestLayout()。这个方法通常是在某个view认为其当前的边界不再适应自身的情况下由其自身调用。
Drawing
Drawing is handled by walking the tree and rendering eachview that intersects the invalid region. Because the tree is traversedin-order, this means that parents will draw before (i.e., behind) theirchildren, with siblings drawn in the order they appear in the tree. If you seta background drawable for a View, then the View will draw it for you beforecalling back to its onDraw() method.
Note that the framework will not draw views that are not inthe invalid region.
To force a view to draw, call invalidate().
通过回调函数onDraw()从上至下对各个View进行绘制。调用invalidate()强制绘制。
Event Handling and Threading
一个View事件处理的基本周期如下:
1. An event comes in and isdispatched to the appropriate view. The view handles the event and notifies anylisteners.
一个事件发生,分发给相应的View,该View处理完事件并通知所有的监听。
2. If in the course of processingthe event, the view's bounds may need to be changed, the view will callrequestLayout().
如果在处理事件的过程中,View的边界发生了变化,将会调用requestLayout()方法进行重新绘制
3. Similarly, if in the course ofprocessing the event the view's appearance may need to be changed, the viewwill call invalidate().
类似的,如果在事件处理中,View的外观发生变化,将会调用invalidate()方法
4. If either requestLayout() orinvalidate() were called, the framework will take care of measuring, layingout, and drawing the tree as appropriate.
无论requestLayout()方法还是invalidate()方法被调用,框架都会处理测量、布局,并适时的绘制View树。
Focus Handling
The framework will handle routine focus movement inresponse to user input. This includes changing the focus as views are removedor hidden, or as new views become available. Views indicate their willingnessto take focus through the isFocusable() method. To change whether a view cantake focus, call setFocusable(boolean). When in touch mode (see notes below)views indicate whether they still would like focus via isFocusableInTouchMode()and can change this via setFocusableInTouchMode(boolean).
框架会处理焦点转移以应对用户输入的响应。这包括当view移动或隐藏或新的view可用时的焦点变化。View通过调用isFocusable()来提示是否需要焦点。调用setFocusable(boolean)来改变某个view是否需要焦点。当处于触摸模式的时候,调用isFocusableInTouchMode()来指明是否任然需要焦点。
Focus movement is based on an algorithm which finds thenearest neighbor in a given direction. In rare cases, the default algorithm maynot match the intended behavior of the developer. In these situations, you canprovide explicit overrides by using these XML attributes in the layout file:
焦点转移是基于给定方向最近相邻的一种算法。在极少情况下,算法产生的效果与开发者的意图可能不一致。在这种情况下,你可以通过在布局文件中指明明确的属性:
nextFocusDown
nextFocusLeft
nextFocusRight
nextFocusUp
Scrolling
The framework provides basic support forviews that wish to internally scroll their content. This includes keeping trackof the X and Y scroll offset as well as mechanisms for drawing scrollbars. SeescrollBy(int, int), scrollTo(int, int), and awakenScrollBars() for moredetails.
框架对views期望能够让其content滚动提供了基本的支持。包括保持跟踪X和Y的偏移量和画滚动条的机制。了解详细细节可以查看scrollBy(int,int),scrollTo(int,int),awakenScrollBars()。
Animation
Starting with Android 3.0, the preferredway of animating views is to use the android.animation package APIs. TheseAnimator-based classes change actual properties of the View object, such asalpha and translationX. This behavior is contrasted to that of the pre-3.0Animation-based classes, which instead animate only how the view is drawn onthe display. In particular, the ViewPropertyAnimator class makes animatingthese View properties particularly easy and efficient.
Alternatively, you can use the pre-3.0animation classes to animate how Views are rendered. You can attach anAnimation object to a view using setAnimation(Animation) orstartAnimation(Animation). The animation can alter the scale, rotation,translation and alpha of a view over time. If the animation is attached to aview that has children, the animation will affect the entire subtree rooted bythat node. When an animation is started, the framework will take care ofredrawing the appropriate views until the animation completes.