* <p> * 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. * </p>
該段文字說明View是1、一個占有矩形屏幕區(qū)域的視圖? 2、負(fù)責(zé)視圖的繪制以及事件處理。? ViewGroup作為View的子類,是進(jìn)行layout的基類。它是一個不可見容器,它可以包含其它的視圖(View)以及視圖組(ViewGroup),并且定義這些視圖和視圖組的Layout屬性
* <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>
所有的view都被指定在Window窗口內(nèi),并且以單個樹結(jié)構(gòu)存在,我們添加View通過代碼添加 或者在一個或多個XML的Layout文件里面添加一個視圖樹。系統(tǒng)提供了很多子類視圖用于控制或者顯示文字、圖片或者其他內(nèi)容。
* <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 handle 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>
一旦創(chuàng)建了一個視圖樹,便會有一些我們希望執(zhí)行的共有的操作:
1、設(shè)置屬性;這些可使用的屬性,可以在不同的子類視圖中產(chǎn)生不同的效果,這些屬性在XML的layout布局文件里面被設(shè)置,在編譯器被系統(tǒng)識別出來后進(jìn)行加載
2、設(shè)置焦點;framework層將處理焦點的移動來響應(yīng)用戶的輸入,如果要強(qiáng)制聚焦一個指定視圖,可以使用requestFocus()方法
3、建立監(jiān)聽器;視圖允許客戶端設(shè)置監(jiān)聽器進(jìn)行通知,當(dāng)有些事件發(fā)生時,來告知視圖。
4、設(shè)置可見性;使用setVisibility()方法進(jìn)行視圖的顯示與不顯示或者隱藏
* <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的framework層進(jìn)行執(zhí)行的,我們不應(yīng)該回調(diào)布局、測量、繪制操作,在我們自己的視圖上,除非我們繼承的是ViewGroup類。
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)}.

當(dāng)我們需要自定義視圖時,只需要使用系統(tǒng)提供的重載方法即可。,不需要全部使用,如上圖提供的這些方法,是使用最多的
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:
Define a Button in the layout file and assign it a unique 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
? ? ? 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.
視圖可以使用一個integer類型的id關(guān)聯(lián)他們,這個id被指定在XML布局文件中,通過使用他們,可以在視圖樹內(nèi),找到他們指定的視圖
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.
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.
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:?getLeft() + getWidth()
視圖是一個矩形圖,視圖都有位置, 表示為一對左坐標(biāo)和一對右坐標(biāo),和2個尺寸。表示為一個寬和一個高。位置和尺寸的單位是像素
我們可以通過getLeft和getTop方法獲取到視圖的位置,getLeft()方法返回的是矩形視圖左邊或X的坐標(biāo),getTop()方法返回的是矩形視圖頂部或Y的坐標(biāo),這些方法返回的視圖是相對于父視圖的位置。
除此之外,還有一些方便的方法被提供,以避免不必要的計算,getRight()、getBottom()。這些方法返回坐標(biāo)的右和底邊緣的矩形坐標(biāo),其中g(shù)etRight()方法和 getLeft()+getWidth()的值是一樣的
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.
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 {@link #getMeasuredWidth()} and {@link #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 {@link #getWidth()} and {@link #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 {@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()}.
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.
大小,內(nèi)邊距和外邊距
大小:一個視圖的大小表示為一個寬和高,一個視圖準(zhǔn)確的說占有2對寬高值。? ?第一對:測量的寬和測量的高,這個尺寸定義了一個視圖在父視圖中的大小,他們獲取的方法為getMeasuredWidth()和getMeasuredHeight()
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第二對:僅僅是寬和高,有時也被稱為繪制寬和繪制高,這個尺寸定義了視圖在屏幕上準(zhǔn)確的大小,在繪制時和布局完之后,這些值是有的,但是卻是不必要的,他們不同于測量寬和測量高,他們獲取的方式為getWidth()和getHeight()方法
內(nèi)邊距:測量視圖尺寸時,我們會考慮他的內(nèi)邊距,內(nèi)邊距用像素表示,是視圖的左、上、右、下的一部分。內(nèi)邊距可以用來偏移視圖內(nèi)容,通過一個指定大小的像數(shù)值例如setPadding(int, int, int, int)、setPaddingRelative(int, int, int, int)、getPaddingLeft()等等
外邊距:即使一個視圖能夠定義一個內(nèi)邊距,但是它不能提供任何外邊距的支持,然而視圖組提供了這樣的引用,詳情需要看ViewGroup類以及android.view.ViewGroup.MarginLayoutParams的內(nèi)容。
Layout
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.
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.
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:
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 {@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.
布局是一個雙傳遞過程:測量傳遞過程與布局傳遞過程。測量傳遞過程的實現(xiàn)使用 measure(int,int)方法,他是一個自上而下的視圖樹的遍歷,在遞歸期間,每個視圖都將尺寸規(guī)范向下推送到視圖樹中,在測量過程完成時,每一個視圖就都存儲了他們的測量值? ? ?第二個傳遞過程發(fā)生在 布局(layout(int,int,int,int))方法中,也是一個自上而下的視圖樹遍歷。在傳遞期間,每一個父視圖的職責(zé)是對他們自己所有的子視圖布局,其中視圖大小使用的是在測量傳遞過程中計算出來的尺寸大小。
當(dāng)一個視圖的measure()方法返回時,它的getMeasuredWidth()和getMeasuredHeight()的值必須被設(shè)置,同時被設(shè)置的還有子節(jié)點中的視圖。一個視圖的測量寬和測量高的值必須遵循父視圖的約束,這保證了在測量傳遞結(jié)束時,所有的父視圖接受了他們子視圖的測量。一個父視圖可能會在他們的子視圖上measure()超過一次,例如:父視圖可能測量了他的每一個子視圖通過unspecified尺寸,以便于找出他們想要的尺寸,隨后再次回調(diào)measure()方法使用準(zhǔn)確的數(shù)值。
測量傳遞使用2個類去傳遞尺寸: MeasureSpec和LayoutParams? ?
MeasureSpec:被視圖用來告訴他們的父視圖,他們想要測量的值和位置是怎樣的,
LayoutParams:僅僅描述他想要的視圖的寬和高想要多大
對于每一個尺寸來說,視圖能夠指定的值為:
1、一個確定的值
2、MATCH_PARENT? 意味著這個視圖想要找父視圖要最大的尺寸
3、WRAP_CONTENT? 表明這個視圖僅僅想要足夠大的尺寸去包裹住他的內(nèi)容就可以了
ViewGroup的子類有不同的LayoutParams子類。
MeasureSpecs被用來將需求由父類推向子類,一個MeasureSpec有3種模式:
1、UNSPECIFIED? 被父類用來決定子視圖所期望的尺寸,例如:LinearLayout 回調(diào)measure(),在他的子類,使用UNSPECIFIED高度和一個EXACTLY 240 寬度用于找出子視圖在寬度為240像素時的高度需要多少
2、EXACTLY? 被父類用來強(qiáng)制指定一個準(zhǔn)確的大小。子類必須使用這個大小,以保證所有他的子節(jié)點都符合這個大小
3、AT_MOST 被父類用來強(qiáng)制指定一個最大尺寸給子類,這個子類必須保證它和他的子節(jié)點都符合這個大小
去初始化一個布局,調(diào)用requestLayout(),這個方法在認(rèn)為它不在適合它當(dāng)前的布局邊界時被它自身調(diào)用。
Drawing
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.
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?onDraw()?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.
To force a view to draw, call {@link #invalidate()}.
繪圖是通過遍歷樹并記錄需要更新的任何視圖的繪圖命令來處理的,在此之后,整棵樹的繪圖命令被發(fā)送到屏幕上,剪貼到新?lián)p壞的區(qū)域
這棵視圖樹大部分是按順序來紀(jì)錄和繪制,在父節(jié)點繪制之后,他們的子節(jié)點與同級節(jié)點繪制是按照他們出現(xiàn)在視圖樹上的順序來進(jìn)行繪制。如果你設(shè)置一個背景圖片給一個視圖,隨后在回調(diào)onDraw()方法之前,將繪制背景。子節(jié)點繪制順序會被覆蓋{通過?ViewGroup#setChildrenDrawingOrderEnabled(boolean) 自定義子節(jié)點的繪制順序}在視圖組中,以及設(shè)置?{通過 #setZ(float) 設(shè)置Z軸數(shù)值} 在視圖上
如果要強(qiáng)制一個視圖去繪制,可以調(diào)用 invalidate();
Event Handling and Threading
The basic cycle of a view is as follows:
1、An event comes in and is dispatched to the appropriate view. The view handles the event and notifies any listeners.
2、If in the course of processing the event, the view's bounds may need to be changed, the view will call {@link #requestLayout()}.
3、Similarly, if in the course of processing the event the view's appearance may need to be changed, the view will call {@link #invalidate()}.
4、If either {@link #requestLayout()} or {@link #invalidate()} were called, the framework will take care of measuring, laying out, and drawing the tree as appropriate.
Note: The entire view tree is single threaded. You must always be on the UI thread when calling any method on any view.?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}.
事件處理和線程
視圖的基本循環(huán)如下:
1、一個事件帶有和被分配到合適的視圖,這個視圖會處理這個事件并通知監(jiān)聽者
2、如果在處理事件的過程中,這個視圖的邊界被改變了,這個視圖將調(diào)用 requestLayout()
3、同樣的,如果在處理事件的過程中,視圖的外觀可能需要更改,這個視圖將調(diào)用 invalidate()
4、如果調(diào)用了requestLayout或者invalidate,framework將負(fù)責(zé)測量,布局,和繪制視圖樹在適當(dāng)?shù)臅r候
注意:如果整棵視圖樹是單一線程,必須保證一直都在主線程中,在回調(diào)任何視圖的任何方法時。如果你在其他線程上做了操作,并且想在這個線程中更新視圖狀態(tài),必須使用 Handler類操作
Focus Handling
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)}.
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:
? nextFocusDown
? nextFocusLeft
? nextFocusRight
? nextFocusUp
To get a particular view to take focus, call {@link #requestFocus()}.
集中處理
franework將處理日常焦點移動以實現(xiàn)用戶的輸入,這里面包含視圖的移除、隱藏、或新視圖可用時 導(dǎo)致的焦點變更 視圖表示他們愿意通過isFocusable()方法獲取焦點,一個視圖是否能夠獲取焦點并進(jìn)行更改,通過調(diào)用setFocusable(boolean)方法。在觸摸模式下,視圖表明是否他們?nèi)匀幌Mㄟ^isFocusableInTouchMode來獲取焦點和通過setFocusableInTouchMode(boolean)來修改焦點
焦點的移動是基于 在給定的方向上找到最近鄰居的算法。在罕見情況下,這種默認(rèn)的算法可能與開發(fā)者的預(yù)期行為不匹配,在這種情形下, 通過在這個布局文件中使用這些XML屬性,你能夠提供顯示重寫。
下一個下邊的焦點
下一個左邊的焦點
下一個右邊的焦點
下一個上邊的焦點
要獲取指定視圖的焦點,調(diào)用requestFocus()
Touch Mode
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'.
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.
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.
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.
當(dāng)用戶通過D-pad等方向鍵導(dǎo)航用戶界面時,如果設(shè)備有觸摸功能的話,有必要將焦點放在可操作的條目上,比如按鈕,這樣用戶就可以看到輸入的內(nèi)容,然而,用戶通過觸摸界面開始與之交互,不再需要總是高亮,或者給焦點,一個指定的視圖,這激發(fā)了一種名為“觸摸模式”的交互模式。
對于一個有觸摸功能的設(shè)備,一旦用戶觸摸了屏幕,這個設(shè)備將進(jìn)入觸摸模式,從這個點開始,只有View的isFocusableInTouchMode()方法為真時,才是可調(diào)焦的,比如文本編輯控件其他可觸摸的視圖,比如button,在觸摸時無法獲取焦點,他們只會出發(fā)點擊監(jiān)聽器
任何時候,用戶點擊了一個方向鍵,比如D-pad方向,視圖設(shè)備將退出觸摸模式,并且找到一個視圖去獲取焦點,這樣用戶可以在不接觸屏幕的情況下繼續(xù)與用戶界面進(jìn)行交互。
觸摸模式的狀態(tài)是通過Activity進(jìn)行維持的,調(diào)用 isInTouchMode()去獲取是否設(shè)備當(dāng)前處于觸摸模式下。
Scrolling
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.
滾動
framework為希望內(nèi)部滾動他們內(nèi)容的視圖提供了基本支持,這包括跟蹤X和Y滾動偏移量以及繪制滾動條的機(jī)制。具體可以看 scrollBy(int,int)方法、scrollTo(int,int)方法、awakenScrollBars() 方法。
Tags
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.
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?} child element:
? ? ? <View ...
? ? ? ? ? ? android:tag="@string/mytag_value" />
? ? ? <View ...>
? ? ? ? ? <tag android:id="@+id/mytag"
? ? ? ? ? ? ? android:value="@string/mytag_value" />
? ? ? </View>
Tags may also be specified with arbitrary objects from code using {@link #setTag(Object)} or {@link #setTag(int, Object)}.
不像IDs,標(biāo)簽不是用來定義視圖的,標(biāo)簽本質(zhì)上是能夠關(guān)聯(lián)到視圖的一條額外的信息,他們常常被用來在視圖中存放有關(guān)視圖的數(shù)據(jù),而不是將他們放在單獨(dú)的結(jié)構(gòu)當(dāng)中
標(biāo)簽可以使用layout的XML中的字符序列值來指定,也可以使用單個{android.R.styleable#View_tag android:tag}屬性,多個標(biāo)簽使用下面這段代碼:
?? ? ? <View ...
? ? ? ? ? ? android:tag="@string/mytag_value" />
? ? ? <View ...>
? ? ? ? ? <tag android:id="@+id/mytag"
? ? ? ? ? ? ? android:value="@string/mytag_value" />
? ? ? </View>
標(biāo)簽也可以使用代碼中任意的object來指定 setTag(Object) 或者setTag(int ,Object).
Themes
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.
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.
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.
? ? ? <LinearLayout
? ? ? ? ? ? ? ...
? ? ? ? ? ? ? android:theme="@android:theme/ThemeOverlay.Material.Dark">
? ? ? ? ? <View ...>
? ? ? </LinearLayout>
主題
默認(rèn)情況下, 視圖使用上下文類提供給他們的構(gòu)造方法的主題來創(chuàng)建,然而,一個不同的主題可以在布局XML通過使用{android.R.styleable#View_theme android:theme}屬性指定或者通過{@link ContextThemeWrapper} 的構(gòu)造方法使用代碼進(jìn)行指定
當(dāng)使用第一種方式時,指定的主題應(yīng)用于頂部填充的上下文主題中(LayoutInflater)? 和 用于視圖本身以及任何子元素
在下面的例子中,2個視圖將使用 Material dark 顏色方案進(jìn)行創(chuàng)建,然而,因為覆蓋主題只定義了屬性的子集,定義在inflation上下文的主題 android.R.styleable#Theme_colorAccent android:colorAccent的值將被保留
Properties
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?Animation?section.
屬性
視圖類公開一個ALPHA屬性,以及幾個與轉(zhuǎn)換相關(guān)的屬性,例如{TRANSLATION_X}和{TRANSLATION_Y}。這些屬性既可以在{Property}表單中使用,也可以在名稱類似的setter/getter方法中使用(例如{setAlpha(float)}用于{ALPHA})。這些屬性可用于在視圖中設(shè)置與這些呈現(xiàn)相關(guān)屬性相關(guān)聯(lián)的持久狀態(tài)。屬性和方法也可以與{android.animation結(jié)合使用?;贏nimator}的動畫,更多介紹在Anim中
Animation
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.
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.
動畫
從3.0開始,優(yōu)先使用的視圖動畫是?android.animation包里面的API,這些??android.animation.Animator Animator ,基于更改視圖類的實際屬性,比如{setAlpha(float) alpha} 和?{ setTranslationX(float) translationX},這個行為與3.0{android.view.animation.Animation Animation}形成了對比,3.0之前它只對視圖在顯示器上的繪制方式進(jìn)行動畫。特別是 ViewPropertyAnimator 類使動畫這些視圖屬性特別容易和有效。
作為選擇,你能使用3.0之前的動畫類來動畫視圖的渲染。你能綁定一個Animation類給視圖使用setAnimation(Animation)或者startAnimation(Animation)這個動畫隨時間的推移能改變大小,旋轉(zhuǎn)、位移、和透明度。如果動畫綁定到一個有子類的視圖中時,這個動畫將影響整個子視圖樹通過那個節(jié)點。當(dāng)一個動畫開始后,framework層將負(fù)責(zé)重新繪制適當(dāng)?shù)囊晥D,直到動畫完成
Security
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.
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.
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}.
安全
有時,應(yīng)用程序必須能夠在用戶完全知情和同意的情況下驗證正在執(zhí)行的操作,比如授予權(quán)限請求,購買或點擊廣告。不幸的是,惡意應(yīng)用程序可能試圖欺騙用戶來執(zhí)行這些操作,不知道的,通過隱藏視圖的預(yù)期目的。作為補(bǔ)救措施,該框架提供了一種觸摸過濾機(jī)制,可用于改進(jìn)提供敏感功能訪問的視圖的安全性。
啟用觸摸過濾,調(diào)用setFilterTouchesWhenObscured(boolean)或者設(shè)置??android:filterTouchesWhenObscured 布局屬性為true。啟用時,當(dāng)視圖窗口被另一個可見窗口遮擋時,框架將丟棄接收到的觸摸。因此,當(dāng)吐司、對話框或其他窗口出現(xiàn)在視圖窗口上方時,視圖將不會接收觸摸。
為了對安全性進(jìn)行更細(xì)粒度的控制,考慮重載onFilterTouchEventForSecurity(MotionEvent) 方法去實現(xiàn)你自己的安全策略,具體看MotionEvent#FLAG_WINDOW_IS_OBSCURED