This class represents the basic building block for user interface components. A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The ViewGroup
subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.
该类表示用户界面组件的基本构建块。View占据屏幕上的矩形区域并且负责绘制和事件处理。View是所有控件的基类,用于创建交互式UI组件(按钮、文本字段等)。ViewGroup子类是所有布局的基类,它是容纳其他View(或者其他ViewGroup)并且定义他们的布局属性的不可见容器。
Using Views
使用View
All of the views in a window are arranged in a single tree. You can add views either from code or by specifying a tree of views in one or more XML layout files. There are many specialized subclasses of views that act as controls or are capable of displaying text, images, or other content.
窗口中的所有视图都是在单个树中排列的。您可以从代码中添加视图,也可以通过在一个或多个XML布局文件中指定视图树来添加视图。有许多专门的子类视图作为控件或能够显示文本、图像或其他内容。
Once you have created a tree of views, there are typically a few types of common operations you may wish to perform:
一旦创建了是视图树,通常会有几种常见的操作,您可能希望执行这些操作:
- Set properties: for example setting the text of a
TextView
. The available properties and the methods that set them will vary among the different subclasses of views. Note that properties that are known at build time can be set in the XML layout files.
设置属性:例如设置TextView的文本。可用属性和设置它们的方法将在View的不同子类中有所不同。注意,可以在XML布局文件中设置生成时已知的属性。
- Set focus: The framework will handle moving focus in response to user input. To force focus to a specific view, call
requestFocus()
.
设置焦点:framework将会响应用户输入来处理移动的焦点。为了强制焦点到特定view,需要调用requestFocus()方法
.
- Set up listeners: Views allow clients to set listeners that will be notified when something interesting happens to the view. For example, all views will let you set a listener to be notified when the view gains or loses focus. You can register such a listener using
setOnFocusChangeListener(android.view.View.OnFocusChangeListener)
. Other view subclasses offer more specialized listeners. For example, a Button exposes a listener to notify clients when the button is clicked.
设置监听器:View允许客户端设置监听器,当视图中发生了一些有趣的事件时,将通知这些监听器。例如,当view获得或失去焦点时,所有视图允许设置监视器去通知它。你可以使用setOnFocusChangeListener(android.view.View.OnFocusChangeListener)方法去注册一个监听器。其他的View子类提供更多的特定监听器。例如,当按钮被点击时,它会暴露一个监听器去唤醒客户端。
- Set visibility: You can hide or show views using
setVisibility(int)
.
设置可见性:你可以使用setVisibility(int)方法设置View隐藏或者显示。
Note: The Android framework is responsible for measuring, laying out and drawing views. You should not call methods that perform these actions on views yourself unless you are actually implementing a ViewGroup
.
注意:Android框架负责测量、布局和绘制视图。除非实际实现ViewGroup
,否则你不应该调用在视图上执行这些操作的方法。
Implementing a Custom View
实现自定义View
To implement a custom view, you will usually begin by providing overrides for some of the standard methods that the framework calls on all views. You do not need to override all of these methods. In fact, you can start by just overriding onDraw(android.graphics.Canvas)
.
为了实现自定义View,通常可以通过为框架调用所有View的一些标准方法提供重写。您不需要重写所有这些方法。事实上,您可以通过重写onDraw(android.graphics.Canvas)
.来开始。
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. 当从代码创建View时,当View从布局文件被填充时,会调用构造函数的形式。第二种形式应该解析和应用定义布局文件的所有属性。 |
| Called after a view and all of its children has been inflated from XML. 当View和其子View被XML文件填充之后调用该方法。 | |
Layout |
| Called to determine the size requirements for this view and all of its children. 调用该方法去决定View和其所有子View的尺寸需求。 |
| Called when this view should assign a size and position to all of its children. 当View需要为其所有子View分配尺寸和位置时调用该方法。 | |
| Called when the size of this view has changed. 当View尺寸发生改变时调用该方法。 | |
Drawing |
| Called when the view should render its content. 当View呈现内容时调用该方法。 |
Event processing |
| Called when a new hardware key event occurs. 当发生新的硬件按键时调用该方法。 |
| Called when a hardware key up event occurs. 当硬件按键抬起事件发生时调用该方法。 | |
| Called when a trackball motion event occurs. 当轨迹球运动事件发生时调用该方法。 | |
| Called when a touch screen motion event occurs. 当触摸屏幕事件发生时调用该方法。 | |
Focus |
| Called when the view gains or loses focus. 当View获得或者失去焦点时调用该方法。 |
| Called when the window containing the view gains or loses focus. 当包含View的Window获得或者失去焦点时调用该方法。 | |
Attaching |
| Called when the view is attached to a window. 当View绑定到Window时调用该方法。 |
| Called when the view is detached from its window. 当View从Window解绑时调用该方法。 | |
| Called when the visibility of the window containing the view has changed. 当包含View的Window可见性发生变化时调用该方法。 |
IDs
Views may have an integer id associated with them. These ids are typically assigned in the layout XML files, and are used to find specific views within the view tree. A common pattern is to:
View可能会有与其相关联的整型ID。这些ID通常分配在布局文件中,并用于在View树中找到具体的View。一个共同的模式是:
Define a Button in the layout file and assign it a unique ID.
在布局文件中定义一个Button并且分配唯一ID。
<Button
android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_button_text"/>
From the onCreate method of an Activity, find the Button
从Activity的onCreate方法中查找该Button:
Button myButton = findViewById(R.id.my_button);
View IDs need not be unique throughout the tree, but it is good practice to ensure that they are at least unique within the part of the tree you are searching.
View的ID在所有的树中不必是唯一的,但这是一个很好的做法去确保它们至少在您正在搜索的树的部分中是唯一的。
Position
位置
The geometry of a view is that of a rectangle. A view has a location, 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 the pixel.
View的几何形式是矩形。一个View有一个位置(坐标),表示为一对左和上的坐标;以及两个维度,表示为宽和高。位置和尺寸的单位是像素。
It is possible to retrieve the location of a view by invoking 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 both return the location of the view relative to its parent. For instance, when getLeft() returns 20, that means the view is located 20 pixels to the right of the left edge of its direct parent.
View有可能通过调用getLeft()和getTop()方法去检索它的位置。前者返回表示View的矩形的左坐标或者X坐标,后者返回表示View的矩形的顶部坐标或者Y坐标,这两个方法返回相对于它们的父View的位置信息。例如,当
getLeft()返回20,那意味着该View位于其直接父类左边缘居右20像素的位置。
In addition, several convenience methods are offered to avoid unnecessary computations, namely getRight()
and getBottom()
. These methods return the coordinates of the right and bottom edges of the rectangle representing the view. For instance, calling getRight()
is similar to the following computation: getLeft() + getWidth()
(see Size for more information about the width.)
除此之外,还有几个方便的方法避免了不必要的计算,分别叫做getRight()和getBottom()。这两个方法返回表示该View的矩形的右部和下部坐标,例如,调用getRight()与下面的计算类似:getLeft() + getWidth()(更多关于宽度的信息请参见
Size)
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的大小由宽和高表示。一个View实际上具有两队宽度和高度值。
The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent (see Layout for more details.) The measured dimensions can be obtained by calling getMeasuredWidth()
and getMeasuredHeight()
.
第一对称为“测量宽度”和“测量高度”。这两个维度定义了一个View要在其父体中有多大(参见Layout以获得更多的细节)。测量维度可通过调用getMeasuredWidth()
和getMeasuredHeight()方法获得。
The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size 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 width and height can be obtained by calling getWidth()
and getHeight()
.
第二对简称为“宽”和“高”,有时也称为“绘制宽度”和“绘制高度”。这两个维度定义了在绘制时和布局后View在屏幕上的实际尺寸。这些值可能但不必须与测量宽度和高度相同。宽度和高度可通过调用 getWidth()
和 getHeight()获得。
To measure its dimensions, a view takes into account its padding. The padding is expressed in pixels for the left, top, right and bottom parts of the view. Padding can be used to offset the content of the view by a specific amount of pixels. For instance, a left padding of 2 will push the view's content by 2 pixels to the right of the left edge. Padding can be set using the setPadding(int, int, int, int)
or setPaddingRelative(int, int, int, int)
method and queried by calling getPaddingLeft()
, getPaddingTop()
, getPaddingRight()
, getPaddingBottom()
, getPaddingStart()
, getPaddingEnd()
.
为了测量它的尺寸,View会计算它的内边距。内边距以View的左,上,右,下部分的像素单位表示。内边距可以用来通过特定的像素量来抵消视图的内容。左边的内边距为2会将View的内容推到其左边缘居右两个像素单位。内边距可以通过setPadding(int, int, int, int)
或者setPaddingRelative(int, int, int, int)方法来设置,并且可以通过调用getPaddingLeft()
, getPaddingTop()
, getPaddingRight()
, getPaddingBottom()
, getPaddingStart()
, getPaddingEnd()方法来查询。
Even though a view can define a padding, it does not provide any support for margins. However, view groups provide such a support. Refer to ViewGroup
and ViewGroup.MarginLayoutParams
for further information.
尽管View可以定义内边距,但它对外边距不提供任何支持。然而,视图组提供这样的支持。有关进一步的信息请参阅ViewGroup
和ViewGroup.MarginLayoutParams。
Layout
布局
Layout is a two pass process: a measure pass and a layout pass. The measuring pass is implemented in measure(int, int)
and is a top-down traversal of the view tree. Each view pushes dimension specifications down the tree during the recursion. At the end of the measure pass, every view has stored its measurements. The second pass happens inlayout(int, int, int, int)
and is also top-down. During this pass each parent is responsible for positioning all of its children using the sizes computed in the measure pass.
布局是一个双向传递过程:测量传递和布局传递。测量传递是通过实现measure(int, int)方法并且是一个对View树进行自上而下遍历的过程。在递归的过程中,每个View推送其尺寸规格到树下。在测量传递结束时,每个View都存储了它的测量值。第二个传递是通过调用layout(int, int, int, int)
方法并且也是自上而下遍历的。在这一过程中,每个父类负责对它的子类在测量过程中计算的尺寸进行定位。
When a view's measure() method returns, its getMeasuredWidth()
and getMeasuredHeight()
values must be set, along with those for all of that view's descendants. A view's measured width and measured height values must respect the constraints imposed by the view's parents. This guarantees that at the end of the measure pass, all parents accept all of their children's measurements. A parent view may call measure() more than once on its children. For example, the parent may measure each child once with unspecified dimensions to find out how big they want to be, then call measure() on them again with actual numbers if the sum of all the children's unconstrained sizes is too big or too small.
当View的measure()方法返回时,它的getMeasuredWidth()
和getMeasuredHeight()方法的值必须被设置,以及所有View的派生类也必须被设置。View的测量宽度和测量高度值必须遵守其父View的强制约束。这保证了在测量结束时,所有的父类会接受它们的子类的测量值。父View可能会多次调用它的子View的
measure()方法。例如,
The measure pass uses two classes to communicate dimensions. The View.MeasureSpec
class is used by views to tell their parents how they want to be measured and positioned. The base LayoutParams class just describes how big the view wants to be for both width and height. For each dimension, it can specify one of:
- an exact number
- MATCH_PARENT, which means the view wants to be as big as its parent (minus padding)
- WRAP_CONTENT, which means that the view wants to be just big enough to enclose its content (plus padding).
There are subclasses of LayoutParams for different subclasses of ViewGroup. For example, AbsoluteLayout has its own subclass of LayoutParams which adds an X and Y value.
MeasureSpecs are used to push requirements down the tree from parent to child. A MeasureSpec can be in one of three modes:
- 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 set to UNSPECIFIED and a width of EXACTLY 240 to find out how tall the child view wants 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 must use this size, and guarantee that all of its descendants will fit within this size.
- AT_MOST: This is used by the parent to impose a maximum size on the child. The child must guarantee that it and all of its descendants will fit within this size.
To initiate a layout, call requestLayout()
. This method is typically called by a view on itself when it believes that is can no longer fit within its current bounds.