Android View 源码解析(一)

来源:互联网 发布:金手指考试软件下载 编辑:程序博客网 时间:2024/05/19 00:10
Android View 源码解析(一)———-民主万岁———-共和万岁这是我的第一篇博客,我其实也是不知道怎样写博客,或者写什么样的博客。既然啥都不知道我就当个技术翻译,从Android源码入手,开始分析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 widgets, which are * used to create interactive UI components (buttons, text fields, etc.). The * {@link android.view.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类。首现说一下,我的英文就是个菜鸡,所以我就用百度翻译给大家介绍一下。注意一下:括号外面的是百度翻译,括号里面的是我的翻译,如果一句话没有带括号就说明我的意思跟百度翻译的是一样的。
 <p> 这个类表示用户界面组件的基本构建块(表示所有的界面组件都是view)。视图在屏幕上占据一个矩形区域,负责绘图和事件处理。View是用于创建交互式UI组件(按钮、文本字段等)的“组件”的基类。这个{@链接Android。观。ViewGroup }类是< EM >布局< / EM >的基类,它是看不见的容器持有其他观点(或其他viewgroup)并确定其布局属性。(ViewGroup 是所有布局的基类),它是看不见的容器持有View或者ViewGroup 并定义它们的布局属性。
这就是google 大神对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>
有关使用此类开发应用程序用户界面的信息 可以参考guide/topics/ui/index.html这个开发文档。 大家在查东西的时候可以看到这个文档,如果里面的英文看的吃力的话,可以选择中文。文档地址见下图。![ 这个是上面文档的地址](http://img.blog.csdn.net/20170306131245551?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjg4NjU5ODk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)。
 * <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>
窗口中的所有视图都被安排在一棵树中。您可以添加视图从代码或通过在一个或多个xml布局中指定视图树文件夹.有许多专门的子视图作为控件或能够显示文本、图像或其他内容。(这里大概介绍一下怎样使用View和View的树结构)
 * <p> * 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> * </ul> * </p>
一旦你创建了一个视图树,通常有几种类型的常见的操作,你可能希望执行: 1.设置属性:例如设置{@链接Android TextView }。小部件。可用的性质和方法它们在不同的子视图中会有所不同。请注意,在生成时已知的属性可以在xml布局中设置文件夹.(根据子View的属性设置属性) 2.设置焦点将处理用户输入响应。强制聚焦到特定视图,调用{“链接# requestfocus }(设置焦点)3.设置侦听器:视图允许客户端设置侦听器这将通知当一些有趣的事情发生的。例如,所有视图将允许您设置侦听器在视图时通知得失焦点。您可以使用这样的监听器注册{“链接# setonfocuschangelistener(Android。视图。视图。OnFocusChangeListener)}。其他视图子类提供更专门的侦听器。例如,一个按钮当单击按钮时,将侦听器通知客户端通知客户端(主要讲view可以和用户实现互动,并监听各种事件,并且将了一个例子)。4.设置可见 setVisibility(int)
 * <p><em> * 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>
Android框架负责测量、布局和绘制视图。你不应该调用方法执行这些方法的意见除非你自己实现了ViewGroup.(主要说 Android框架会自己实现 view的测量 布局和绘制)。
 * <a name="Lifecycle"></a> * <h3>Implementing a Custom View</h3>
声明周期 实现自定义View
* <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)}. * <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> *     </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. *         </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> *     </tr> *     <tr> *         <td><code>{@link #onSizeChanged(int, int, int, int)}</code></td> *         <td>Called when the size of this view has changed. *         </td> *     </tr> * *     <tr> *         <td>Drawing</td> *         <td><code>{@link #onDraw(android.graphics.Canvas)}</code></td> *         <td>Called when the view should render its content. *         </td> *     </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> *     </tr> *     <tr> *         <td><code>{@link #onKeyUp(int, KeyEvent)}</code></td> *         <td>Called when a hardware key up event occurs. *         </td> *     </tr> *     <tr> *         <td><code>{@link #onTrackballEvent(MotionEvent)}</code></td> *         <td>Called when a trackball motion event occurs. *         </td> *     </tr> *     <tr> *         <td><code>{@link #onTouchEvent(MotionEvent)}</code></td> *         <td>Called when a touch screen motion event occurs. *         </td> *     </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> *     </tr> * *     <tr> *         <td><code>{@link #onWindowFocusChanged(boolean)}</code></td> *         <td>Called when the window containing the view gains or loses focus. *         </td> *     </tr> * *     <tr> *         <td rowspan="3">Attaching</td> *         <td><code>{@link #onAttachedToWindow()}</code></td> *         <td>Called when the view is attached to a window. *         </td> *     </tr> * *     <tr> *         <td><code>{@link #onDetachedFromWindow}</code></td> *         <td>Called when the view is detached from its window. *         </td> *     </tr> * *     <tr> *         <td><code>{@link #onWindowVisibilityChanged(int)}</code></td> *         <td>Called when the visibility of the window containing the view *         has changed. *         </td> *     </tr> *     </tbody> * * </table> * </p>

实现一个自定义视图,通常你会开始覆盖框架调用所有视图的一些标准方法。你做的不需要重写所有这些方法。事实上,你可以从开始重写{@link #onDraw(android.graphics.Canvas}开始。 (主要讲自定义的View补兵重写View的所有方法,你可以从onDraw()方法开始练习。(onDraw()负责的是View 的绘制)).![这里写图片描述](http://img.blog.csdn.net/20170306141819863?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjg4NjU5ODk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)以上是对上一段源发的翻译。

<a name="IDs"></a> * <h3>IDs</h3> * 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:
Id: 视图可能具有与它们相关联的整数id。这些IDS通常在布局中指定xml文件,并用于查找特定的内部视图视树 常见的模式有:
* <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. * </p>
以上讲了一个例子讲了一下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. * </p> * * <p> * 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> *
Position:

视图的几何形状是矩形的。视图有位置,表示为左和顶部坐标,和以宽度和高度表示的两个维度。定位单元尺寸是像素

通过调用方法获取他的相对位置。前者返回表示视图的矩形的左、或x坐标。后者返回表示视图的矩形的顶部或y坐标。 这些方法都返回视图相对于其父的位置。例如,当getleft()返回20,这意味着观点是20像素右父左边右。

此外,一些方便的方法,以避免不必要的计算,即{ getright() }和{ getbottom() }。这些方法返回的右边缘和底部边缘的坐标表示视图的矩形。例如,调用{getright() }类似于下面的计算:getLeft() + getWidth()。

* <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()}. * </p> * * <p> * 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()}. * </p> * * <p> * 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>
Size ,Padding和Margin:

视图的大小用宽度和高度表示。实际上具有两对宽度和高度值

第一对被称为测量宽度和测量高度 这些维度定义了一个视图要多大在其父母测量的尺寸可以通过调用 测量宽度和测量高度可以调用 {getMeasuredWidth()和getMeasuredHeight()}

第二对是简单的称为宽度和高度,有时称图纸宽度和绘图高度。这些维度定义屏幕上的视图的实际大小,在绘图时间和布局后。这些值可以,但不必,不同于测得的宽度和高度。宽度和高度可以通过调用{ getwidth() }和{getheight() }。

Padding为了测量它的尺寸,一个视图考虑到它的填充。填料以视图的上、下、左和右部分的像素表示。填充可以用来抵消视图的具体内容像素。例如,一个2的左填充将推动视图的内容左边缘右2像素。可以使用 {setpadding(int,int,int,int)}或{setpaddingrelative(int,int,int,int)}方法和查询调用{getpaddingleft() },{getpaddingtop() },{getpaddingright() },{ getpaddingbottom() },{ getpaddingstart() }, {getpaddingend() }。

Margin 即使视图可以定义填充,它也不提供任何支持Margin 。但是,ViewGroup提供这样的支持。参阅{@链接ViewGroup }的{ ViewGroup.marginlayoutparams }。(View支持padding 但是不支持Margin ViewGroup支持Margin 因为ViewGroup内部有一个Marginlayoutparams )

* <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. * </p> * * <p> * 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. * </p> * * <p> * 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. * </ul> * </p> * * <p> * 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>

重点:

《测量》
layout是同过两个步骤调用的:1. onMeasure 2. onLayout 测量通过调用{measure(int,int)}是一个自上而下遍历View树。在递归过程中每个View将宽高向下推到树上。在measure传递结束时,每个视图都存储它的测量的宽高。
第二步骤发生在{lay布局(int,int,int,int)}也是自上而下的。在这一关每个父View都负责定位其所有的子View使用测量中计算的尺寸。

当一个视图的measure()方法返回时,它 getmeasuredwidth() }{getmeasuredheight() }值必须设置,连同所有View的后代都设定了。视图的测量宽度和测量高度值必须遵守父View强加的限制。这保证了在测量结束时,所有的父View接受他们的所有子View测量。父视图可以不止一次调用measure()去测量子View。例如,家长可以测量每个孩子一次未指定的尺寸,以找出他们想多大,如果所有子View他们measure()无约束尺寸或者过大或过小,然后调用实际数字。(当一个View调用measure()方法返回时,必须设置getmeasuredwidth() 和getmeasuredheight()连同所有View的后代都设定了。View的测量宽度和测量高度值必须遵守父View强加的限制 ,这保证了在测量结束时,所有的父View接受他们的所有子View测量。父视图可以不止一次调用measure()去测量子View。例如,家长可以测量每个孩子一次未指定的 ,以找出他们想多大,如果所有子View他们measure()无约束尺寸或者过大或过小,然后调用实际数字。 这里其实已经讲了measure()方法)

度量传递使用两个类来传递维度。这个{measurespec }类使用的告诉父容器如何想要被测量和定位。LayoutParams 类 参数类描述视图的宽度和高度要有多大。对于每个尺寸,它可以指定一个测量模式:

精确数字 MATCH_PARENT :这意味着这个视图要和它的父容器一样大(减去paddding) WRAP_CONTENT:这意味着该视图只想足够大的区域去包裹内容 有不同的 ViewGroup LayoutParams的子类。例如,AbsoluteLayout包含LayoutParams子类拥有一个X和Y值。

MeasureSpecs 用来将测量需求从父容器传给子View。一个测量模式可以是一下的三种模式之一

UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式EXACTLY是指精确尺寸: 当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width=”50dip”,或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸AT_MOS是最大尺寸:当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸

要初始化一个布局,调用{requestLayout方法}。当它认为不能在当前范围内适应时,该方法通常被视图本身调用.(我们可以理解为重新布局了一下。 当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view重新调用他onMeasure onLayout来对重新设置自己位置。特别的当view的layoutparameter发生改变,并且它的值还没能应用到view上,这时候适合调用这个方法。)

 * <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. * </p> * * <p> * 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. * </p> * * <p> * To force a view to draw, call {@link #invalidate()}. * </p>

重点

《绘制》

Draw 是通过在View树上行走并记录需要更新的视图的绘制命令。在此之后,绘制命令的整棵View树被发到屏幕,裁剪到新损坏的区域。(调用view的绘绘制方法会绘制View和剪裁View)

View的绘制在很大程度上是按顺序记录和绘制的,之前是父母画的(即,落后)他们的孩子,兄弟姐妹按照他们出现的顺序在树上。如果你设定了一个背景的一个视图,然后将绘制自己在调用 onDraw()将之前。孩子绘图顺序可以覆盖{ViewGroup setchildrendrawingorderenabled(boolean)定制子View绘画秩序}在一个ViewGroup,与{setz(float)} }自定义Z值设置在View上。

调用view绘制的方法invalidate() View本身调用迫使view重画。

 * * <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}. * </p>
《事件处理和线程》

view 的循环基本如下:

一个事件进来并被发送到适当的视图。视图处理该事件并通知listeners,如果在处理事件的过程中,视图的边界可能需要要改变,视图将调用{requestlayout() } 同样,如果在处理事件的过程中视图的外观可能需要改变,视图将调用{ invalidate() } 如果 requestlayout() }或{ invalidate() }被调用,该框架将在适当的时候托管 测量排版,并绘制View树。

注意:整个视图树是单线程的。在任何视图上调用任何方法时的必须是在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 * </pre> * </p> * * * <p> * To get a particular view to take focus, call {@link #requestFocus()}. * </p>
《焦点处理》

框架将处理日常焦点运动响应用户输入。这包括改变焦点的视图被删除或隐藏,或作为新的视图变得可用。View绘制后可以通过{isFocusable()}获取焦点。设置View室友拥有焦点,叫{ setfocusable(boolean)}. 当在触摸模式下可以通过(isfocusableintouchmode()方法)表名View是否拥有焦点。调用(setfocusableintouchmode(boolean)方法)可以改变view的焦点。

焦点运动是基于一个算法,发现最近给定命令的邻居。在极少数情况下,默认算法可能不匹配开发者的预期行为。在这些情况下,可以在布局文件中使用以下的属性:

*
 * nextFocusDown * nextFocusLeft * nextFocusRight * nextFocusUp * 

一些特别的View调用 {requestFocus()} 何以获取焦点

 * <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. * </p> * <p> * 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>
《触摸模式》 用户界面将通过方向键如 D-pad 给用户指引,有必要给用户操作的条目上给上焦点例如,button,这样用户就明白将要输入什么。如果设备具有触摸功能,不管怎样,当用户通过界面发生交互时,它就没有必要是高亮的,或者继续拥有焦点,或者是一个特殊的View.这种互动模式命名为“触摸模式”。 对于这种可触摸的设备,当触摸屏幕的时候,设备就是触摸模式。从这点起,只有获得焦点的控件{#isFocusableInTouchMode}是true ru:可编辑的文本。 其他的View是可触摸的,如按钮,触摸时不带焦点;他们只会触发Click监听。任何时候一个用户点击一个方向键,如方向键方向,查看装置将退出触摸模式,并找到一个视图获取焦点,这样用户可以恢复与用户界面的交互无需再次触摸屏幕触摸模式的状态可以通过{{ android.app.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>

《滑动》

框架提供一些基本的内部自动滑动的View。这包括跟踪x和y滚动偏移以及绘制滚动机制。 See * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and * {@link #awakenScrollBars()} for more details. * 请查看scrollBy(int, int),scrollTo(int, int)和awakenScrollBars() 获取更多的信息。

 * <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>
《标签》

与IDS不同,标签不用于识别视图。标签本质上是额外的信息,可以与视图关联。他们是最通常用于方便存储与视图中的视图相关的数据而不是把它们放在一个单独的结构中。

 * <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. * </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> * <p> * Tags may be specified with character sequence values in layout XML as either * a single tag using the {@link android.R.styleable#View_tag android:tag} * attribute or multiple tags using the {@code <tag>} child element: * <pre> *     &ltView ... *           android:tag="@string/mytag_value" /&gt; *     &ltView ...&gt; *         &lttag android:id="@+id/mytag" *              android:value="@string/mytag_value" /&gt; *     &lt/View> * </pre> * </p> * <p> * Tags may also be specified with arbitrary objects from code using * {@link #setTag(Object)} or {@link #setTag(int, Object)}. * </p>
《Tag 标签》

与IDS不同,标签不用于识别视图。标签本质上是额外的信息,可以与视图关联。他们是最通常用于方便存储与视图中的视图相关的数据而不是把它们放在一个单独的结构中。(本质就是view存储数据 的结构)

标签可以在XML布局中使用字符序列值指定为使用属性,或使用多个子元素的为其tag的值 (具体可以看一下 ListView 的Adapter 中的 ViewHolder 的使用 )

标签也可以指定任意对象{ settag(object)}或{ settag(int,object)}。

 * <a name="Themes"></a> * <h3>Themes</h3> * <p> * By default, Views are created using the theme of the Context object supplied * to their constructor; however, a different theme may be specified by using * the {@link android.R.styleable#View_theme android:theme} attribute in layout * XML or by passing a {@link ContextThemeWrapper} to the constructor from * code. * </p> * <p> * When the {@link android.R.styleable#View_theme android:theme} attribute is * used in XML, the specified theme is applied on top of the inflation * context's theme (see {@link LayoutInflater}) and used for the view itself as * well as any child elements. * </p> * <p> * In the following example, both views will be created using the Material dark * color scheme; however, because an overlay theme is used which only defines a * subset of attributes, the value of * {@link android.R.styleable#Theme_colorAccent android:colorAccent} defined on * the inflation context's theme (e.g. the Activity theme) will be preserved. * <pre> *     &ltLinearLayout *             ... *             android:theme="@android:theme/ThemeOverlay.Material.Dark"&gt; *         &ltView ...&gt; *     &lt/LinearLayout&gt; * </pre> * </p> *
《主题 Themes》

默认情况下,使用Context的主题创建视图他们的构造函数或者可以使用指定的不同主题。这个{@link android.R.styleable#View_theme android:theme}XML属性或通过{@link ContextThemeWrapper}的构造代码。

当在xml中指定属性{@link android.R.styleable#View_theme android:theme},指定的主题应用于Context主题(LayoutInflater })和用于自己以及任何子元素。

使用的View使用 Material dark 主题,请参照下面的例子 :

Theme 属性是 在Android 5.0 之后推出来 。view上直接使用主题的应用场景不是很多,大家要用的话推荐使用 stytle属性。

 * <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. * </p>
《属性 Properties 》

View 中有很多的属性,可以 查看他们的get()和set() 方法。这些属性可以用于在veiw上设置与呈现相关属性相关联的持久状态. 这些属性可以和动画配合使用。

 * <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>
《动画 Animation》

从Android 3.0 开始,动画视图的首选是{@link android.animation}包中的 APIs. 这些{{@link android.animation.Animator Animator}基类改变view的实际属性 例如: {@link #setAlpha(float) alpha} and{@link #setTranslationX(float) translationX}.这些行为在3.0后已经被{@link android.view.animation.Animation Animation}代替。特别是,{@link ViewPropertyAnimator} 类使属性动画变得更高效和容易。

你可以在view上使用{setAnimation(Animation)}或者{startAnimation(Animation)}去展示一个动画。动画可以在一段时间后使view 平移 旋转 放大 透明度改变

如果一个字View 上的动画,这个动画将会影响这个节点下的所有 View 树。底层将会刷新这个view知道动画结束。

 * <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}. * </p>

《安全 Security》

有时,一个应用程序能够验证一个动作执行必须是用户同意且充分认识是非常必要的如授予许可请求,购买或点击广告。不幸的是,一个恶意应用程序可能试图欺骗用户通过隐藏视图目的来执行这些动作。作为补救措施,该框架提供了一个触摸过滤机制,可用于提高提供敏感功能访问的视图的安全性。

过滤触摸,调用 {@link #setFilterTouchesWhenObscured(boolean)}或者在布局文件中 设置 android:filterTouchesWhenObscured 属性为true 启用时,每当视图窗口被另一可见窗口遮挡时框架将丢弃所接收到的这个 view的触摸。 因此,当toast 对话框或者其他 的窗口出现时 这个view将不接收触摸事件。

对于更细粒度的安全控制,考虑重写 { onfiltertoucheventforsecurity(MotionEvent)}方法来实现自己的安全策略。参阅{@link MotionEvent#FLAG_WINDOW_IS_OBSCURED }

* @attr ref android.R.styleable#View_alpha//关联方法: setAlpha(float) 属性说明: 视图透明度,值在0-1之间。0为完全透明,1为完全不透明。 * @attr ref android.R.styleable#View_background关联方法: setBackgroundResource(int) 属性说明: 视图背景 * @attr ref android.R.styleable#View_clickable 关联方法: setClickable(boolean) 属性说明: 视图是否可点击 * @attr ref android.R.styleable#View_contentDescription// 对于一些视力有障碍的用户,android提供给用户一个很有用的功能,可以帮助使用app。  这个属性必须在用户的Accessible 中的相应属性开启后才能使用。点击Accessible控件,android系统会自动使用人声朗读控件上android:contentDescription属性说指向的内容。  这个属性的主要功能就是为视力有障碍的人增加对控件的解释。 * @attr ref android.R.styleable#View_drawingCacheQuality// 关联方法: setDrawingCacheQuality(int) 属性说明: "设置绘图时半透明质量。有可以取以下3个值 auto——默认,由框架决定 high——高质量,使用较高的颜色深度,消耗更多的内存 low——低质量,使用较低的颜色深度,但是用更少的内存" * @attr ref android.R.styleable#View_duplicateParentState//关联方法: 属性说明: 如果设置此属性,将直接从父容器中获取绘图状态(光标,按下等) * @attr ref android.R.styleable#View_id//关联方法: setId(int) 属性说明: 给当前View设置一个在当前layout.xml中的唯一编号,可以通过调用View.findViewById() 或Activity.findViewById()根据这个编号查找到对应的View。不同的layout.xml之间定义相同的id不会冲突。 * @attr ref android.R.styleable#View_requiresFadingEdge // 关联方法:  setVerticalFadingEdgeEnabled(boolean) 属性说明: 定义滚动时边缘是否褪色 * @attr ref android.R.styleable#View_fadeScrollbars //关联方法: setScrollbarFadingEnabled(boolean) 属性说明: 定义在ScrollBar没有使用时,是否褪色。 * @attr ref android.R.styleable#View_fadingEdgeLength 关联方法: getVerticalFadingEdgeLength() 属性说明: 设置边框渐变的长度。 * @attr ref android.R.styleable#View_filterTouchesWhenObscured //关联方法:setFilterTouchesWhenObscured(boolean) 属性说明: view所在窗口被其它可见窗口遮住时,是否过滤触摸事件。 * @attr ref android.R.styleable#View_fitsSystemWindows //  关联方法: setFitsSystemWindows(boolean) 属性说明: 设置布局调整时是否考虑系统窗口(如状态栏) * @attr ref android.R.styleable#View_isScrollContainer * @attr ref android.R.styleable#View_focusable // 关联方法: setFocusable(boolean) 属性说明: 设置是否获得焦点。若有requestFocus()被调用时,后者优先处理。注意在表单中想设置某一个如EditText获取焦点,光设置这个是不行的,需要将这个EditText前面的focusable都设置为false才行。在Touch模式下获取焦点需要设置focusableInTouchMode为true。 * @attr ref android.R.styleable#View_focusableInTouchMode // 关联方法: setFocusableInTouchMode(boolean) 属性说明: 设置在Touch模式下View是否能取得焦点。 * @attr ref android.R.styleable#View_hapticFeedbackEnabled  关联方法: setHapticFeedbackEnabled(boolean) 属性说明: 是否启用触摸反馈,启用后就是在点击等操作时会有震动等反馈效果 * @attr ref android.R.styleable#View_keepScreenOn //关联方法: setKeepScreenOn(boolean) 属性说明: 视图在可见的情况下是否保持唤醒状态。 * @attr ref android.R.styleable#View_layerType //  关联方法: setLayerType(int,Paint) 属性说明: "设置指定层的类型,可以取以下3个值: none——不指定 software——软件层。 hardware——硬件层。使用硬件加速。 * @attr ref android.R.styleable#View_layoutDirection // 关联方法: setLayoutDirection(int) 属性说明: 定义布局图纸的方向 * @attr ref android.R.styleable#View_longClickable //关联方法: setLongClickable(boolean) 属性说明: 是否响应长点击事件 * @attr ref android.R.styleable#View_minHeight //关联方法: setMinimumHeight(int) 属性说明: 设置视图最小高度 * @attr ref android.R.styleable#View_minWidth//关联方法: setMinimumWidth(int) 属性说明: 设置视图最小宽度 * @attr ref android.R.styleable#View_nextFocusDown// 关联方法: setNextFocusDownId(int) 属性说明: 向下移动焦点时,下一个获取焦点的view的id * @attr ref android.R.styleable#View_nextFocusLeft// 关联方法: setNextFocusLeftId(int) 属性说明: 向左移动焦点时,下一个获取焦点的view的id * @attr ref android.R.styleable#View_nextFocusRight//关联方法: setNextFocusRightId(int) 属性说明: 向右移动焦点时,下一个获取焦点的view的id * @attr ref android.R.styleable#View_nextFocusUp// 关联方法: setNextFocusForwardId(int) 属性说明: 向上移动焦点时,下一个获取焦点的view的id * @attr ref android.R.styleable#View_onClick//关联方法: 属性说明: 点击时,要调用的方法的名称。 * @attr ref android.R.styleable#View_padding// 关联方法: setPaddingRelative(int,int,int,int) 属性说明: 设置上下左右的边距 * @attr ref android.R.styleable#View_paddingBottom//关联方法: setPaddingRelative(int,int,int,int) 属性说明: 下边距 * @attr ref android.R.styleable#View_paddingLeft// 左边距 * @attr ref android.R.styleable#View_paddingRight//右边距 * @attr ref android.R.styleable#View_paddingTop//上边距 * @attr ref android.R.styleable#View_paddingStart//相当于左边距 * @attr ref android.R.styleable#View_paddingEnd//相当于右边距 * @attr ref android.R.styleable#View_saveEnabled// 关联方法: setSaveEnabled(boolean) 属性说明: 在配置改变等情况出现时是否保存view的状态数据。如果你的view有id,那默认系统就会帮你保存。 * @attr ref android.R.styleable#View_rotation//关联方法: setRotation(float) 属性说明: 旋转度数 * @attr ref android.R.styleable#View_rotationX//关联方法: setRotationX(float) 属性说明: 水平旋转度数 * @attr ref android.R.styleable#View_rotationY//关联方法: setRotationY(float) 属性说明: 竖直旋转度数 * @attr ref android.R.styleable#View_scaleX//关联方法: setScaleX(float) 属性说明: 水平方向缩放比例 * @attr ref android.R.styleable#View_scaleY//关联方法: setScaleY(float) 属性说明: 竖直方向缩放比例 * @attr ref android.R.styleable#View_scrollX//关联方法: 属性说明: x方向的滚动偏移。即在水平方向滚动了多少距离 * @attr ref android.R.styleable#View_scrollY//关联方法: 属性说明: y方向的滚动偏移。即在竖直方向滚动了多少距离 * @attr ref android.R.styleable#View_scrollbarSize// 关联方法: setScrollBarSize(int) 属性说明: 设置滚动条的尺寸。垂直滚动条的宽度、水平滚动条的高度 * @attr ref android.R.styleable#View_scrollbarStyle// 关联方法: setScrollBarStyle(int) 属性说明: "滚动条的风格。共4组值: insideOverlay——内贴图 insideInset——内插图 outsideOverlay——外贴图 outsideInset——外插图。 inside就是滚动条在绘制在padding以内;outside就是不需要绘制在padding内(即view的边界处);Overlay是贴图,就是直接覆盖在内容的上方,这样内容可能会显示到滚动条下方去;Inset是插图,就是会在对应padding上加上滚动条的宽度,以不让内容显示到滚动条下面去。" * @attr ref android.R.styleable#View_scrollbars// 关联方法: 属性说明: "设置可显示的滚动条。有3个取值: none——不显示滚动条 horizontal——显示水平滚动条 vertical——显示竖直滚动条"  * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade//关联方法: setScrollBarDefaultDelayBeforeFade(int) 属性说明: 滚动条在n毫秒后开始淡出。 * @attr ref android.R.styleable#View_scrollbarFadeDuration// 关联方法: setScrollBarFadeDuration(int) 属性说明: 滚动条用多长时间淡出完毕 * @attr ref android.R.styleable#View_scrollbarTrackHorizontal// 关联方法: 属性说明: 是否总是绘制水平滚动条的滚动轨道 * @attr ref android.R.styleable#View_scrollbarThumbHorizontal//关联方法: 属性说明: 是否总是绘制竖直滚动条的滚动轨道 * @attr ref android.R.styleable#View_scrollbarThumbHorizontal // 关联方法: 属性说明: 水平滚动块的drawable对象 * @attr ref android.R.styleable#View_scrollbarTrackVertical//关联方法: 属性说明: 竖直滚动条滚动轨道的drawable对象 * @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack// 关联方法: 属性说明: 水平滚动条滚动轨道的drawable对象 * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack// * @attr ref android.R.styleable#View_stateListAnimator// * @attr ref android.R.styleable#View_transitionName// * @attr ref android.R.styleable#View_soundEffectsEnabled// * @attr ref android.R.styleable#View_tag//关联方法: 属性说明: string标识。类似id,id是整数标识。 * @attr ref android.R.styleable#View_textAlignment// 关联方法: setTextAlignment(int) 属性说明: 设置文本的显示方式。 * @attr ref android.R.styleable#View_textDirection//  关联方法: setTextDirection(int) 属性说明: 设置文本的显示方向。 * @attr ref android.R.styleable#View_transformPivotX// 关联方法: setPivotX(float) 属性说明: 水平方向偏转量 * @attr ref android.R.styleable#View_transformPivotY// 关联方法: setPivotY(float) 属性说明: 竖直方向偏转量 * @attr ref android.R.styleable#View_translationX// 关联方法: setTranslationX(float) 属性说明: 水平方向的移动距离 * @attr ref android.R.styleable#View_translationY//关联方法: setTranslationY(float) 属性说明: 竖直方向的移动距离 * @attr ref android.R.styleable#View_translationZ//关联方法: setTranslationY(float) 属性说明: Z方向的移动距离 * @attr ref android.R.styleable#View_visibility//关联方法: setVisibility(int) 属性说明: "view的可见性。有3个取值: gone——不可见,同时不占用view的空间; invisible——不可见,但占用view的空间; visible——可见" * @attr ref android.R.styleable#View_theme// 主题
1 0
原创粉丝点击