android动画延迟执行,Android 过渡动画框架
為了幫助視圖層次內(nèi)部和視圖之間的過(guò)渡更加容易實(shí)現(xiàn)動(dòng)畫(huà)效果,Android 提供了 Transition 框架。這一套框架能夠在視圖之間提供一種或者多種動(dòng)畫(huà)過(guò)渡效果。過(guò)渡動(dòng)畫(huà)要解決的另一個(gè)主要問(wèn)題就是對(duì)同一場(chǎng)景中的多個(gè) View 做動(dòng)畫(huà),彌補(bǔ)了之前Android 在動(dòng)畫(huà)方面的缺失。
這一套框架提供如下功能:
Group-level 動(dòng)畫(huà)
在同一視圖層次中一種或者多種動(dòng)畫(huà)效果
Transition-based 動(dòng)畫(huà)
在初始場(chǎng)景和終止場(chǎng)景之間動(dòng)畫(huà)
Built-in 動(dòng)畫(huà)
內(nèi)置普通效果動(dòng)畫(huà),包括 fade out 和 movement
Resource 文件支持
從 layout 資源文件中加載視圖以及內(nèi)置動(dòng)畫(huà)資源
Lifecycle callbacks
隨心所欲的控制動(dòng)畫(huà)的過(guò)程
Transition API 在 Android 5.0 及以上被引入,但是在 4.4 Kitkat 時(shí)就引入了 Scenes 和 Transitions 的概念。在 Android 4.0 API level 14 及以上,可以使用 android.support.transition 包中內(nèi)容
創(chuàng)建場(chǎng)景
Scene 保存視圖狀態(tài)及層次結(jié)構(gòu),包括所有的視圖及其屬性。 Transition 框架能夠從場(chǎng)景到場(chǎng)景進(jìn)行過(guò)渡動(dòng)畫(huà)。初始場(chǎng)景(Staring scene)經(jīng)常是當(dāng)前的視圖層次,而結(jié)束場(chǎng)景(ending scene)通常由用戶從 layout 創(chuàng)建或者用代碼從一組視圖中創(chuàng)建。
從 Layout 創(chuàng)建 Scene
利用靜態(tài)方法 Scene.getSceneForLayout()
// Create the scene root for the scenes in this app
mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);
// Create the scenes
mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
mAnotherScene =
Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);
或者使用構(gòu)造函數(shù)構(gòu)造:
Scene mScene;
// Obtain the scene root element
mSceneRoot = (ViewGroup) mSomeLayoutElement;
// Obtain the view hierarchy to add as a child of
// the scene root when this scene is entered
mViewHierarchy = (ViewGroup) someOtherLayoutElement;
// Create a scene
mScene = new Scene(mSceneRoot, mViewHierarchy);
場(chǎng)景間動(dòng)畫(huà)
一般情況下 Android 系統(tǒng)會(huì)自動(dòng)在場(chǎng)景間動(dòng)畫(huà),自定義動(dòng)畫(huà)可省略,但是如果想自定義動(dòng)畫(huà),可以在場(chǎng)景退出或者進(jìn)入的時(shí)候自定義動(dòng)畫(huà),需要注意以下兩點(diǎn):
動(dòng)畫(huà)視圖不在同一個(gè)視圖層次
Transition 框架不能給 Listview 自動(dòng)創(chuàng)建動(dòng)畫(huà),Transition 框架的限制
可以使用 Scene.setExitAction(Runnable action) 或者 Scene.setEnterAction(Runnable action) 來(lái)自定義進(jìn)入或者退出的動(dòng)作。
Scene 總結(jié)
Scene 類中幾個(gè)重要的方法:
構(gòu)造方法,Scene(ViewGroup sceneRoot, View layout)。 從 Layout 中創(chuàng)建 Scene,當(dāng)調(diào)用 enter() 方法時(shí)將 sceneRoot 下子view 全部移除并將新 Layout 中內(nèi)容填充。
靜態(tài)方法,創(chuàng)建新 Scene getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context)
enter() 方法 exit() 方法
setEnterAction(Runnable action) 和 setExitAction(Runnable action)
Transition
在 Transition 框架中,動(dòng)畫(huà)在開(kāi)始和結(jié)束場(chǎng)景間創(chuàng)建了一系列動(dòng)畫(huà)幀。
創(chuàng)建 Transition
系統(tǒng)提供的內(nèi)置 transition 有如下:
Class
Tag
Attributes
Effect
AutoTransition
-
默認(rèn)過(guò)渡動(dòng)畫(huà),Fade out 漸隱, move 位移 和 resize 大小縮放,fade in 漸顯 ,按順序
Fade
android:fadingMode=”[fade_in fade_out fade_in_out]”
fade_in_out (default) 漸隱之后跟隨者 漸顯
ChangeBounds
-
位移和縮放
通過(guò)資源文件創(chuàng)建
也通過(guò)資源文件即可修改過(guò)渡效果,避免大幅度修改 Activity 中代碼。并且通過(guò)資源文件方式創(chuàng)建有效地將復(fù)雜的動(dòng)畫(huà)和代碼文件分離。
通過(guò)如下步驟添加過(guò)渡動(dòng)畫(huà)資源:
添加 res/transition/ 目錄
在該目錄下創(chuàng)建 XML 資源
在 XML 文件中添加內(nèi)置的過(guò)渡動(dòng)畫(huà)子節(jié)點(diǎn)
例如如下資源文件則指定了漸隱漸顯動(dòng)畫(huà), res/transition/fade_transition.xml :
利用如下代碼片段從資源文件中創(chuàng)建 Transition:
Transition mFadeTransition =
TransitionInflater.from(this).
inflateTransition(R.transition.fade_transition);
通過(guò)代碼創(chuàng)建 Transition
可以在代碼中動(dòng)態(tài)地創(chuàng)建過(guò)渡效果,可以通過(guò)非常少的代碼創(chuàng)建。通過(guò)直接調(diào)用 Transition 的子類構(gòu)造函數(shù)直接創(chuàng)建,例如:
Transition mFadeTransition = new Fade();
執(zhí)行 Transition
直接調(diào)用 TransitionManager.go() 靜態(tài)方法,并提供一個(gè)終止場(chǎng)景:
TransitionManager.go(mEndingScene, mFadeTransition);
如果不指定 transition ,則系統(tǒng)自動(dòng)套用默認(rèn)的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)。
選擇特定目標(biāo)
轉(zhuǎn)場(chǎng)動(dòng)畫(huà)默認(rèn)對(duì)所有的Views進(jìn)行動(dòng)畫(huà),如果只希望某一些特定的 Views 動(dòng)畫(huà),或者某一些不做動(dòng)畫(huà)。 在 transition 中,每一個(gè)視圖都被稱作一個(gè) target,但是得注意,只有在Scene 中的views 才被稱作 target。
可以使用 removeTarget() 來(lái)從 transition 中移除某一個(gè) view,或者使用 addTarget() 來(lái)給 Transition 添加一個(gè) view。
使用多重動(dòng)畫(huà)
如下定義的 transitionSet 和 AutoTransition 表現(xiàn)一致:
android:transitionOrdering="sequential">
代碼中可以使用 TransitionInflater.from() 來(lái)加載 TransitionSet ,因?yàn)?TransitionSet 繼承自 Transition,因此可以像使用 Transition 一樣使用 TransitionSet。
不使用 Scene 來(lái)使用 Transition
改變視圖層次并不是唯一改變UI的方式,同樣也可以通過(guò)添加、修改、移除子view來(lái)對(duì)當(dāng)前的視圖作出修改。或者當(dāng)兩個(gè)場(chǎng)景非常相似,為了避免維護(hù)兩份近乎一致的視圖層次,可以只維護(hù)一份,并做一些微小的調(diào)整。
此時(shí)可以使用 delayed transition 來(lái)在兩個(gè)狀態(tài)之間進(jìn)行轉(zhuǎn)換。Transition 系統(tǒng)自動(dòng)選擇當(dāng)前的視圖層次作為初始狀態(tài),并記錄用戶對(duì)視圖的修改,然后應(yīng)用為終止?fàn)顟B(tài),并在之后進(jìn)行動(dòng)態(tài)地變化。
在單一視圖中使用 delay transition :
調(diào)用 ` TransitionManager.beginDelayedTransition()` 來(lái)提供提供一個(gè)父view包括所有的待變化的view,此時(shí)系統(tǒng)自動(dòng)保存當(dāng)前傳入的所有 views 的狀態(tài)及屬性
修改子views ,系統(tǒng)會(huì)記錄該views 的變化
當(dāng)系統(tǒng)重繪時(shí)系統(tǒng)自動(dòng)在原始及新?tīng)顟B(tài)間做動(dòng)畫(huà)
創(chuàng)建自定義 Transitions
自定義過(guò)渡動(dòng)畫(huà)(custom transition)可以實(shí)現(xiàn)區(qū)別于內(nèi)置轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的效果。比如,你可以定義一個(gè)動(dòng)畫(huà)來(lái)將文字和輸入框的前景顏色變成灰色來(lái)表示當(dāng)前禁止輸入。
繼承 Transition 類
繼承 Transition 類,并實(shí)現(xiàn)如下方法:
public class CustomTransition extends Transition {
@Override
public void captureStartValues(TransitionValues values) {}
@Override
public void captureEndValues(TransitionValues values) {}
@Override
public Animator createAnimator(ViewGroup sceneRoot,
TransitionValues startValues,
TransitionValues endValues) {}
}
Transition 動(dòng)畫(huà)使用 property 動(dòng)畫(huà)系統(tǒng),屬性動(dòng)畫(huà)動(dòng)態(tài)地修改視圖的屬性,因此得知道初始和終止的值。
captureStartValues
系統(tǒng)會(huì)對(duì)初始場(chǎng)景中的每一個(gè)view調(diào)用 captureStartValues(transitionValues) ,參數(shù) TransitionValues 對(duì)象包含了一個(gè)指向 view 的引用和一個(gè)保存view狀態(tài)的 Map 實(shí)例。在自己的實(shí)現(xiàn)中,獲取這些屬性,并將這些屬性傳回給map。
為了避免key 值和已經(jīng)擁有的key值矛盾,可以使用如下的 TransitionValues 鍵的形式:
package_name:transition_name:property_name
例如下面的例子:
public class CustomTransition extends Transition {
// Define a key for storing a property value in
// TransitionValues.values with the syntax
// package_name:transition_class:property_name to avoid collisions
private static final String PROPNAME_BACKGROUND =
"com.example.android.customtransition:CustomTransition:background";
@Override
public void captureStartValues(TransitionValues transitionValues) {
// Call the convenience method captureValues
captureValues(transitionValues);
}
// For the view in transitionValues.view, get the values you
// want and put them in transitionValues.values
private void captureValues(TransitionValues transitionValues) {
// Get a reference to the view
View view = transitionValues.view;
// Store its background property in the values map
transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
}
...
}
captureEndValues
系統(tǒng)會(huì)給終止場(chǎng)景中的每一個(gè)target view自動(dòng)調(diào)用 ` captureEndValues(TransitionValues),其他方面,captureEndValues()和captureStartValues()` 表現(xiàn)一致。
animator
在初始和終止視圖層次間進(jìn)行動(dòng)畫(huà),提供一個(gè) animator ,通過(guò)復(fù)寫(xiě) createAnimator() ,當(dāng)系統(tǒng)調(diào)用此方法時(shí),他將 root view 和開(kāi)始和結(jié)束 TransitionValues 傳入。系統(tǒng)調(diào)用 createAnimator() 方法的次數(shù)由開(kāi)始和終止場(chǎng)景之間的變化決定。
Android 系統(tǒng)自帶 Transition
雖然教程上只羅列了一些 Transition ,但是看文檔,還是能發(fā)現(xiàn)不少 Transition 的直接子類。
Transition
Transition 在 XML 定義時(shí)有如下屬性:
android:duration 動(dòng)畫(huà)時(shí)長(zhǎng)毫秒
android:interpolator 動(dòng)畫(huà)使用的 interpolator
android:matchOrder 過(guò)渡動(dòng)畫(huà)執(zhí)行順序
android:startDelay 在過(guò)渡動(dòng)畫(huà)之前延遲時(shí)間 毫秒
TransitionSet
TransitionSet 在 XML 中有如下屬性:
android:transitionOrdering 過(guò)渡動(dòng)畫(huà)執(zhí)行順序,有兩種值, together 和 sequential
以下轉(zhuǎn)場(chǎng)動(dòng)畫(huà)中原生提供的包括 Fade,Slide,Explode,但場(chǎng)景之間存在共享元素時(shí),有如下的轉(zhuǎn)場(chǎng)動(dòng)畫(huà) changeBound,changeClipBounds,changeImageTransform,ChangeTransform,ChangeScroll。
Fade
漸隱漸顯動(dòng)畫(huà)
Fade 在 XML 中有如下屬性:
android:fadingMode 漸變模式, fade_in, fade_out , fade_in_out ,默認(rèn)為 fade_in_out
Slide
元素從四個(gè)方向滑動(dòng)進(jìn)入
Slide 屬性:
android:slideEdge 從那邊滑動(dòng)出,有 left, top, right, bottom, start, end 模式
Explode
屏幕中間上下移走
ChangeBounds
通過(guò)獲取前后Scene 中 target view 的邊界,并對(duì)這些 view 做動(dòng)畫(huà),改變 View 的大小
ChangeClipBounds
獲取前后 Scene 中 getClipBounds() 的邊界,并做動(dòng)畫(huà),有如下屬性:
android:resizeClip 通過(guò)改變 clipBounds 來(lái)改變 view,而不是改變view 自身的大小
ChangeImageTransform
通過(guò)獲取開(kāi)始和結(jié)束時(shí) Scene 中 ImageView 的 matrix ,并對(duì)他們做動(dòng)畫(huà)。 和 ChangeBounds 一起使用,來(lái)對(duì) ImageView 改變大小,形狀,和 ScaleType 來(lái)使動(dòng)畫(huà)更加流暢。
ChangeTransform
獲取 Scene 中的尺寸和旋轉(zhuǎn)角度,并做動(dòng)畫(huà),有如下屬性:
android:reparent 追蹤父view 的變化
android:reparentWithOverlay A parent change should use an overlay or affect the transform of the transitionining View.
ChangeScroll
改變滑動(dòng)位置
下面分享一個(gè) transitionSet 的 XML 語(yǔ)法:
android:transitionOrdering="sequential">
以上就是文檔中對(duì) Transition 的解釋,關(guān)于自定義 Transition 還可以具體展開(kāi)細(xì)講,但是因?yàn)?Transition API 要求的 API 版本比較高,基本 Android 5.0 及以上才可以很好的支持,所以目前使用并不廣,但是相信不久以后就能看到越來(lái)越多的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)了。
reference
總結(jié)
以上是生活随笔為你收集整理的android动画延迟执行,Android 过渡动画框架的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: z最大子数组c语言,关于最大子数组问题
- 下一篇: android 文件存储 集合,Andr