android.view.View

 * 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 <em>widgets</em>, which are
 * used to create interactive UI components (buttons, text fields, etc.). The
 * {@link android.view.ViewGroup} subclass is the base class for <em>layouts</em>, which
 * are invisible containers that hold other Views (or other ViewGroups) and define
 * their layout properties.

View类是UI组件的基本单元,一个View占据了屏幕上的一块矩形区域,并且负责Drawing和Event Handling事件处理,View是widgets的基类,widgets用于创建交互组件(比如Buttons,Text fields等) ViewGroup子类是看不见的容器,用来包含其他View控件并且定义他们的布局属性。

 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For information about using this class to develop your application's user interface,
 * read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> developer guide.
 * </div>
 *
 * <a name="Using"></a>
 * <h3>Using Views</h3>
 * <p>
 * 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.
 * </p>
 * <p>

所有位于window窗口的View都被安排在一个树中,你可以从代码或者在XML布局文件里面添加View,View有非常多的子类用于组件或者能够显示文字,图片或者其他内容

 * Once you have created a tree of views, there are typically a few types of
 * common operations you may wish to perform:
 * <ul>
 * <li><strong>Set properties:</strong> for example setting the text of a
 * {@link android.widget.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.</li>
 * <li><strong>Set focus:</strong> The framework will handled moving focus in
 * response to user input. To force focus to a specific view, call
 * {@link #requestFocus}.</li>
 * <li><strong>Set up listeners:</strong> 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
 * {@link #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.</li>
 * <li><strong>Set visibility:</strong> You can hide or show views using
 * {@link #setVisibility(int)}.</li>

一旦你创造了一个View,通常你需要执行一些基本的操作:设置属性,比如TextView的Text,这些可用的属性和方法会使得子类不同,注意这些属性是在编译期间就可以设置到XML布局文件的

设置焦点:框架会处理焦点的移动来反应用户的输入,强制焦点到一个具体的View,调用requestFocus方法

设置监听器:View允许客户端设置监听器,当关注的事件发生时会被通知,比如所有的监听器都允许设置一个监听器用来坚挺焦点的失去或获得,你可以注册setOnFocusChangedListener,其他的

View子类提供了非常多的具体的监听器,比如Button包罗了一个监听器,当按钮被单击的时候

设置可见性:你可以隐藏或者显示View通过setVisibilit方法

 * 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
 * {@link android.view.ViewGroup}.
 * </em></p>
 *
 * <a name="Lifecycle"></a>
 * <h3>Implementing a Custom View</h3>
 *
 * <p>
 * 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 {@link #onDraw(android.graphics.Canvas)}.

注意:Android框架负责measuring,laying Out和Drawing Views你自己不要调用方法去执行这些操作,除非你自己实现了一个???

实现定制View

为了实现一个定制View,一般你需要提供重写的标注方法,框架会在所有View都调用的,你不必重写所有的这些方法,事实上,只要重写OnDrown(android.graphics.Canvas)就可以

<table border="2" width="85%" align="center" cellpadding="5">
 *     <thead>
 *         <tr><th>Category</th> <th>Methods</th> <th>Description</th></tr>
 *     </thead>
 *  类别, 方法,描述
 *     <tbody>
 *     <tr>
 *         <td rowspan="2">Creation</td>
 *         <td>Constructors</td>
 *         <td>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.
 *         </td>

    创建,构造函数, 当从代码创建或者从布局文件inflate的时候,会有构造函数被电泳,第二种会接卸并且所有在布局文件里定义的属性
 *     </tr>
 *     <tr>
 *         <td><code>{@link #onFinishInflate()}</code></td>
 *         <td>Called after a view and all of its children has been inflated
 *         from XML.</td>
 *     </tr>
 *
 *     <tr>
 *         <td rowspan="3">Layout</td>
 *         <td><code>{@link #onMeasure(int, int)}</code></td>
 *         <td>Called to determine the size requirements for this view and all
 *         of its children.

布局,OnMeasure,调用此方法决定View的大小以及他的子控件
 *         </td>
 *     </tr>
 *     <tr>
 *         <td><code>{@link #onLayout(boolean, int, int, int, int)}</code></td>
 *         <td>Called when this view should assign a size and position to all
 *         of its children.
 *         </td>

  Onlayout,当View对它子控件指定大小和位置的时候调用
 *     </tr>
 *     <tr>
 *         <td><code>{@link #onSizeChanged(int, int, int, int)}</code></td>
 *         <td>Called when the size of this view has changed.
 *         </td>

OnSizeChanged,当View大小变化时调用
 *     </tr>
 *
 *     <tr>
 *         <td>Drawing</td>
 *         <td><code>{@link #onDraw(android.graphics.Canvas)}</code></td>
 *         <td>Called when the view should render its content.
 *         </td>

OnDraw,当View需要呈现内容的时候调用
 *     </tr>
 *
 *     <tr>
 *         <td rowspan="4">Event processing</td>
 *         <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
 *         <td>Called when a new hardware key event occurs.
 *         </td>

事件处理,OnKeyDown  ,当硬盘按键发生时调用
 *     </tr>
 *     <tr>
 *         <td><code>{@link #onKeyUp(int, KeyEvent)}</code></td>
 *         <td>Called when a hardware key up event occurs.
 *         </td>

OnKeyUp,当键盘按钮起时发生
 *     </tr>
 *     <tr>
 *         <td><code>{@link #onTrackballEvent(MotionEvent)}</code></td>
 *         <td>Called when a trackball motion event occurs.
 *         </td>

OnTrackballEvent,当一个轨迹事件发生调用
 *     </tr>
 *     <tr>
 *         <td><code>{@link #onTouchEvent(MotionEvent)}</code></td>
 *         <td>Called when a touch screen motion event occurs.
 *         </td>

OnTouchEvent,当一个触屏操作发生时调用
 *     </tr>
 *
 *     <tr>
 *         <td rowspan="2">Focus</td>
 *         <td><code>{@link #onFocusChanged(boolean, int, android.graphics.Rect)}</code></td>
 *         <td>Called when the view gains or loses focus.
 *         </td>

OnFocusChanged,当View焦点变化时调用
 *     </tr>
 *
 *     <tr>
 *         <td><code>{@link #onWindowFocusChanged(boolean)}</code></td>
 *         <td>Called when the window containing the view gains or loses focus.
 *         </td>

onWindowFocusChanged,当包含View的Window焦点变化时发生
 *     </tr>
 *
 *     <tr>
 *         <td rowspan="3">Attaching</td>
 *         <td><code>{@link #onAttachedToWindow()}</code></td>
 *         <td>Called when the view is attached to a window.
 *         </td>

onAttachedToWindow,当view被附加到一个window时发生
 *     </tr>
 *
 *     <tr>
 *         <td><code>{@link #onDetachedFromWindow}</code></td>
 *         <td>Called when the view is detached from its window.
 *         </td>

onDetachedFromWindow,当从Window中分离时发生
 *     </tr>
 *
 *     <tr>
 *         <td><code>{@link #onWindowVisibilityChanged(int)}</code></td>
 *         <td>Called when the visibility of the window containing the view
 *         has changed.
 *         </td>

onWindowVisibilityChanged,当包含view的window可见性变化时发生
 *     </tr>
 *     </tbody>
 *
 * </table>
 * </p>

 * 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:
 * <ul>
 * <li>Define a Button in the layout file and assign it a unique ID.
 * <pre>
 * &lt;Button
 *     android:id="@+id/my_button"
 *     android:layout_width="wrap_content"
 *     android:layout_height="wrap_content"
 *     android:text="@string/my_button_text"/&gt;
 * </pre></li>
 * <li>From the onCreate method of an Activity, find the Button
 * <pre class="prettyprint">
 *      Button myButton = (Button) findViewById(R.id.my_button);
 * </pre></li>
 * </ul>
 * <p>
 * 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关联,一般这个ID可能在布局文件中指定,以便用于在View Tree中分辨他们,一个常用的方式是:在布局文件中顶一个Button,并制定一个唯一的ID

在Activity的onCreate方法里面找到这个Button, Button myButton = (Button)findViewById(R.id.my_button);

在整个tree中,View ID不需要是唯一的,但是确保它在我们查找的树分叉中是唯一的是好的习惯

 * <a name="Position"></a>
 * <h3>Position</h3>
 * <p>
 * The geometry of a view is that of a rectangle. A view has a location,
 * expressed as a pair of <em>left</em> and <em>top</em> coordinates, and
 * two dimensions, expressed as a width and a height. The unit for location
 * and dimensions is the pixel.
 * </p>
 *
 * <p>
 * It is possible to retrieve the location of a view by invoking the methods
 * {@link #getLeft()} and {@link #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的几何形状是一个矩形,他有一个Location属性,用left,top共同表达,两个尺寸,width,height,这两个单位的单元都是pixel像素,你可以通过调用getLeft(),getTop()来获得一个View的location

前面返回的是left或者X,后面返回的是top或者Y,这些方法返回的位置都是相对于它的父控件来说的,举例,getLeft()返回20,一位置举例它直接父亲的左边20像素

In addition, several convenience methods are offered to avoid unnecessary
 * computations, namely {@link #getRight()} and {@link #getBottom()}.
 * These methods return the coordinates of the right and bottom edges of the
 * rectangle representing the view. For instance, calling {@link #getRight()}
 * is similar to the following computation: <code>getLeft() + getWidth()</code>
 * (see <a href="#SizePaddingMargins">Size</a> for more information about the width.)
 * </p>
 *
 * <a name="SizePaddingMargins"></a>
 * <h3>Size, padding and margins</h3>
 * <p>
 * The size of a view is expressed with a width and a height. A view actually
 * possess two pairs of width and height values.
 * </p>
 *
 * <p>
 * The first pair is known as <em>measured width</em> and
 * <em>measured height</em>. These dimensions define how big a view wants to be
 * within its parent (see <a href="#Layout">Layout</a> for more details.) The
 * measured dimensions can be obtained by calling {@link #getMeasuredWidth()}
 * and {@link #getMeasuredHeight()}.

另外还提供了几个简便的方法来减少不必要的计算,比如getRight(),getBottom(),这两个方法返回矩形区域距右边和底部的距离,getRight()类似于下面的计算:getLeft()+getWidth()

Size,Padding,Margin, View的大小是用width和height表示的,一个View事实上有两两个width和heigth值

第一个是 measured width,measured height,它定义了一个View在父控件里面的尺寸大小,measured尺寸可以通过调用getMeasuredWidth()和getMeasuredHeight()来获得

The second pair is simply known as <em>width</em> and <em>height</em>, or
 * sometimes <em>drawing width</em> and <em>drawing height</em>. 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
 * {@link #getWidth()} and {@link #getHeight()}.
 * </p>
 *
 * <p>
 * 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
 * {@link #setPadding(int, int, int, int)} or {@link #setPaddingRelative(int, int, int, int)}
 * method and queried by calling {@link #getPaddingLeft()}, {@link #getPaddingTop()},
 * {@link #getPaddingRight()}, {@link #getPaddingBottom()}, {@link #getPaddingStart()},
 * {@link #getPaddingEnd()}.

第二对就是width和height,有时也称作drawing width,drawing height,这个尺寸定义了View布局完后在屏幕上的大小,这个值有可能跟measuredWidth和measuredHeight是不同的,但不是必须的,你可以调用

getWidth(),getHeight()来获得

测量它的大小,你需要考虑到Padding,padding是用View的左,上,右,下来表示的,它用来表示view内容的偏移量,举例,left padding 2将会把view的内容向右移动2个像素,可以用setPadding(int,int,int,int)

setPaddingRelative(int,int,int,int)设置padding,或者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
 * {@link android.view.ViewGroup} and
 * {@link android.view.ViewGroup.MarginLayoutParams} for further information.
 * </p>
 *
 * <a name="Layout"></a>
 * <h3>Layout</h3>
 * <p>
 * Layout is a two pass process: a measure pass and a layout pass. The measuring
 * pass is implemented in {@link #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 in
 * {@link #layout(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.
 * </p>
 *
 * <p>
 * When a view's measure() method returns, its {@link #getMeasuredWidth()} and
 * {@link #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可以设置Padding,不提供对Margin的支持,但是ViewGroup提供了这个支持,参考ViewGroup, MarginLayoutParams

布局:

布局有两个极端,一个是Measure PASS,另一个是Layout PASS,Measure pass是通过measure(int,int)方法实现的,在tree下面是组织严密的实现,

Tree下的View递归的Push它的详细数据,在measure pass的结尾,每一个view都会存储它的尺寸大小,第二个layout pass,是通过layout(int,int,int,int)实现的,也是组织严密的,

在这个阶段,每一个父控件为它的子控件负责

当measure()返回时,它的getMeasuredWidth(),getMeasuredHeight()必须设置,连同其所有的子视图,一个View的测量宽度,测量高度必须遵从父视图添加的约束,可以保证在测量阶段

所有的父视图都可以接受子视图的测量参数,一个父视图可能不止一次在子视图上调用measure()方法举例,当父视图无法确定子视图多大的时候就会调用

The measure pass uses two classes to communicate dimensions. The
 * {@link 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:
 * <ul>
 * <li> an exact number
 * <li>MATCH_PARENT, which means the view wants to be as big as its parent
 * (minus padding)
 * <li> WRAP_CONTENT, which means that the view wants to be just big enough to
 * enclose its content (plus padding).
 * </ul>
 * 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.

measure阶段使用两个类去交流尺寸,MeasureSpec用来告诉父视图,他们想被测算和放置在哪,LayoutParams用来描述自己的狂傲,对于每个尺寸,可以指定:

an exact number, MATCH_PARENT跟父视图一样大, WRAP_CONTENT,根据内容调整,

 * MeasureSpecs are used to push requirements down the tree from parent to
 * child. A MeasureSpec can be in one of three modes:
 * <ul>
 * <li>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.
 * <li>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.
 * <li>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.

MeasureSpec用来将父视图的需求传递给子视图,可以是以下几种模式

UNSPECIFIED,父视图决定期望子视图的大小

EXACTLY,父视图给你一个准确的大小

AT_MOST,父视图给定一个最大值

To intiate a layout, call {@link #requestLayout}. This method is typically
 * called by a view on itself when it believes that is can no longer fit within
 * its current bounds.
 * </p>
 *
 * <a name="Drawing"></a>
 * <h3>Drawing</h3>
 * <p>
 * Drawing is handled by walking the tree and recording the drawing commands of
 * any View that needs to update. After this, the drawing commands of the
 * entire tree are issued to screen, clipped to the newly damaged area.

发起一个布局,调用requestLayout()这个方法是view自身调用的,当他确信已经不再适应当前的边界

Drawing是View需要更新的时候被调用的,然后,整个Tree的Drawing命令被发布到屏幕上,那个损坏的区域,

The tree is largely recorded and drawn in order, with parents drawn before
 * (i.e., behind) their children, with siblings drawn in the order they appear
 * in the tree. If you set a background drawable for a View, then the View will
 * draw it before calling back to its <code>onDraw()</code> method. The child
 * drawing order can be overridden with
 * {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean) custom child drawing order}
 * in a ViewGroup, and with {@link #setZ(float)} custom Z values} set on Views.

tree的record和draw是有顺序的,父视图先于子视图,按照在树中的兄弟顺序,如果你给一个View设置背景,这个View就会绘制他在调用OnDraw()方法之前,子视图可以覆盖。。

To force a view to draw, call {@link #invalidate()}.
 * </p>
 *
 * <a name="EventHandlingThreading"></a>
 * <h3>Event Handling and Threading</h3>
 * <p>
 * The basic cycle of a view is as follows:
 * <ol>
 * <li>An event comes in and is dispatched to the appropriate view. The view
 * handles the event and notifies any listeners.</li>
 * <li>If in the course of processing the event, the view's bounds may need
 * to be changed, the view will call {@link #requestLayout()}.</li>
 * <li>Similarly, if in the course of processing the event the view's appearance
 * may need to be changed, the view will call {@link #invalidate()}.</li>
 * <li>If either {@link #requestLayout()} or {@link #invalidate()} were called,
 * the framework will take care of measuring, laying out, and drawing the tree
 * as appropriate.</li>
 * </ol>
 * </p>
 *
 * <p><em>Note: The entire view tree is single threaded. You must always be on
 * the UI thread when calling any method on any view.</em>
 * If you are doing work on other threads and want to update the state of a view
 * from that thread, you should use a {@link Handler}.

强制View绘画,调用invalidate()

事件处理线程

View的生命周期:一个时间发生,并被分发到相应的View上进行处理,并通知相应的监听器

在事件处理的阶段,view的边界可能会发生变化,view会调用requestLayout()同样,如果view的外观发生变化,会调用invalidate(),如果requestLayout活着invalidate呗调用,框架会measuing,layingout,drawing相应的

注意:整个view tree是单线程的,你必须总是在UI线程上调用这些方法,如果你在其他线程上进行工作,然后香葱这个线程更新UI的状态,你应该使用Handler

<a name="FocusHandling"></a>
 * <h3>Focus Handling</h3>
 * <p>
 * The framework will handle routine focus movement in response to user input.
 * This includes changing the focus as views are removed or hidden, or as new
 * views become available. Views indicate their willingness to take focus
 * through the {@link #isFocusable} method. To change whether a view can take
 * focus, call {@link #setFocusable(boolean)}.  When in touch mode (see notes below)
 * views indicate whether they still would like focus via {@link #isFocusableInTouchMode}
 * and can change this via {@link #setFocusableInTouchMode(boolean)}.
 * </p>
 * <p>
 * Focus movement is based on an algorithm which finds the nearest neighbor in a
 * given direction. In rare cases, the default algorithm may not match the
 * intended behavior of the developer. In these situations, you can provide
 * explicit overrides by using these XML attributes in the layout file:
 * <pre>
 * nextFocusDown
 * nextFocusLeft
 * nextFocusRight
 * nextFocusUp

强制处理:框架会处理焦点移动来应对用户的输入,比如改变焦点,当view被移除或隐藏,或者新的View变的可用,view可以通过isFocusable来表达是否接受了焦点,

可以用过setFocusable(boolean)来改变节点,在触摸模式下,可以利用isFocusableInTouchMode setFocusableInTouchMode(boolean)

焦点的移动可以基于寻找最近的邻居,在一个给定的方向上,有些情况下,默认的算法可能不适合开发者,这样,你可以显示的使用XML属性在布局文件中...

 To get a particular view to take focus, call {@link #requestFocus()}.
 * </p>
 *
 * <a name="TouchMode"></a>
 * <h3>Touch Mode</h3>
 * <p>
 * When a user is navigating a user interface via directional keys such as a D-pad, it is
 * necessary to give focus to actionable items such as buttons so the user can see
 * what will take input.  If the device has touch capabilities, however, and the user
 * begins interacting with the interface by touching it, it is no longer necessary to
 * always highlight, or give focus to, a particular view.  This motivates a mode
 * for interaction named 'touch mode'.
 * </p>
 * <p>
 * For a touch capable device, once the user touches the screen, the device
 * will enter touch mode.  From this point onward, only views for which
 * {@link #isFocusableInTouchMode} is true will be focusable, such as text editing widgets.
 * Other views that are touchable, like buttons, will not take focus when touched; they will
 * only fire the on click listeners.

为了使一个特殊的view获得焦点,可以用requestFoucs()方法

触屏模式:当用户通过十字键在用户界面导航的时候,又必须给相应按钮焦点,以便用户能够看到谁能接受输入,如果设备对触屏兼容,

并且用户通过触摸与其进行交互,就没有必须给他一个焦点或者高亮了,这种相应模式称之为“触摸模式”

对于一个兼容触摸的设备,一旦用户触摸屏幕,设备就进入了触摸模式,从这点上来说只有 isFocusableInTouchMode是True的才能获得焦点,比如editing widgets,其他的

是可以触摸的,比如Button,但是当被触摸的时候并不接受焦点,只能触发单击监听器

Any time a user hits a directional key, such as a D-pad direction, the view device will
 * exit touch mode, and find a view to take focus, so that the user may resume interacting
 * with the user interface without touching the screen again.
 * </p>
 * <p>
 * The touch mode state is maintained across {@link android.app.Activity}s.  Call
 * {@link #isInTouchMode} to see whether the device is currently in touch mode.
 * </p>

任何时候,只要用户使用方向键,设备就会推出触摸模式,找到一个View来接受焦点,所以用户就需要重新与用户界面进行交互在不能触摸屏幕的情况下

触摸模式的状态是由 Activity维护的,可以调用isInTouchMode来查看设备当前是否处在触摸模式下!

<a name="Scrolling"></a>
 * <h3>Scrolling</h3>
 * <p>
 * The framework provides basic support for views that wish to internally
 * scroll their content. This includes keeping track of the X and Y scroll
 * offset as well as mechanisms for drawing scrollbars. See
 * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and
 * {@link #awakenScrollBars()} for more details.
 * </p>
 *
 * <a name="Tags"></a>
 * <h3>Tags</h3>
 * <p>
 * Unlike IDs, tags are not used to identify views. Tags are essentially an
 * extra piece of information that can be associated with a view. They are most
 * often used as a convenience to store data related to views in the views
 * themselves rather than by putting them in a separate structure.
 * </p>

滚动:框架提供了对滚动内部内容的支持,包括追踪XY,可以参考scrollBy(int,int) scrollTo(int,int) awakenScrollBars()

标签

不同于ID,标签不是用于辨别View,标签是一份额外的信息附加到View上,经常是存储数据关联到View,而不是把他们放到一个单独的结构中去

<a name="Properties"></a>
 * <h3>Properties</h3>
 * <p>
 * The View class exposes an {@link #ALPHA} property, as well as several transform-related
 * properties, such as {@link #TRANSLATION_X} and {@link #TRANSLATION_Y}. These properties are
 * available both in the {@link Property} form as well as in similarly-named setter/getter
 * methods (such as {@link #setAlpha(float)} for {@link #ALPHA}). These properties can
 * be used to set persistent state associated with these rendering-related properties on the view.
 * The properties and methods can also be used in conjunction with
 * {@link android.animation.Animator Animator}-based animations, described more in the
 * <a href="#Animation">Animation</a> section.

<a name="Animation"></a>
 * <h3>Animation</h3>
 * <p>
 * Starting with Android 3.0, the preferred way of animating views is to use the
 * {@link android.animation} package APIs. These {@link android.animation.Animator Animator}-based
 * classes change actual properties of the View object, such as {@link #setAlpha(float) alpha} and
 * {@link #setTranslationX(float) translationX}. This behavior is contrasted to that of the pre-3.0
 * {@link android.view.animation.Animation Animation}-based classes, which instead animate only
 * how the view is drawn on the display. In particular, the {@link ViewPropertyAnimator} class
 * makes animating these View properties particularly easy and efficient.
 * </p>
 * <p>
 * Alternatively, you can use the pre-3.0 animation classes to animate how Views are rendered.
 * You can attach an {@link Animation} object to a view using
 * {@link #setAnimation(Animation)} or
 * {@link #startAnimation(Animation)}. The animation can alter the scale,
 * rotation, translation and alpha of a view over time. If the animation is
 * attached to a view that has children, the animation will affect the entire
 * subtree rooted by that node. When an animation is started, the framework will
 * take care of redrawing the appropriate views until the animation completes.
 * </p>
 *
 * <a name="Security"></a>
 * <h3>Security</h3>
 * <p>
 * Sometimes it is essential that an application be able to verify that an action
 * is being performed with the full knowledge and consent of the user, such as
 * granting a permission request, making a purchase or clicking on an advertisement.
 * Unfortunately, a malicious application could try to spoof the user into
 * performing these actions, unaware, by concealing the intended purpose of the view.
 * As a remedy, the framework offers a touch filtering mechanism that can be used to
 * improve the security of views that provide access to sensitive functionality.
 * </p><p>
 * To enable touch filtering, call {@link #setFilterTouchesWhenObscured(boolean)} or set the
 * android:filterTouchesWhenObscured layout attribute to true.  When enabled, the framework
 * will discard touches that are received whenever the view's window is obscured by
 * another visible window.  As a result, the view will not receive touches whenever a
 * toast, dialog or other window appears above the view's window.
 * </p><p>
 * For more fine-grained control over security, consider overriding the
 * {@link #onFilterTouchEventForSecurity(MotionEvent)} method to implement your own
 * security policy. See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}.

原文地址:https://www.cnblogs.com/niuge/p/4607717.html