效果
注: 地址見最下方Reference
使用條件
- Android 4.4.2 (API level 19) or higher
什么是Scene和Transition
Android 4.4.2引入transition框架氓侧,可以簡化不同View hierarchies之間的變化的動畫操作脊另,這是通過動態(tài)改views的屬性值來實現(xiàn)的。Scene和Transition是transition框架中的兩個類约巷,其中:
- Scene存儲view hierarchy的狀態(tài)偎痛,包括所有包含的views及其屬性
- Transition存儲動畫信息
transition框架中的結構關系圖:
為什么需要Scene和Transiton
用戶界面經常需要響應用戶的各種操作,為了保證用戶操作的連續(xù)性载庭,可以用動畫來過渡不同界面間的切換和變化看彼,這樣不僅可以給用戶操作反饋還可以幫助用戶理解如何去操作,總結一句話: 一切為了體驗囚聚。
使用方法
- 為需要變化的view hierarchies創(chuàng)建相應的scenes
- 給想使用的動畫創(chuàng)建tansitions
- 用transition manager的相關方法來執(zhí)行動畫
詳細使用方法如下:
1. Scene的創(chuàng)建:
1.1 通過layout資源文件創(chuàng)建
1.2 通過代碼創(chuàng)建
詳細描述如下:
1.1 通過layout資源文件創(chuàng)建
res/layout/a_scene.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scene_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/text_view1
android:text="Text Line 1" />
<TextView
android:id="@+id/text_view2
android:text="Text Line 2" />
</RelativeLayout>
使用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);
1.2 通過代碼創(chuàng)建
使用 Scene(sceneRoot, viewHierarchy)來創(chuàng)建靖榕,實際上等同于Scene.getSceneForLayout(),區(qū)別在于viewHierarchy是否已經加載了顽铸,例如:
// 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);
2. 創(chuàng)建Transition
在資源文件中是自帶的transition是茁计,有以下三個步驟:
1. 在res下添加transition文件夾res/transition/
2. 在該文件夾下創(chuàng)建資源文件
3. 添加一個自帶的transition的節(jié)點<fade/>
.
例如:
res/transition/fade_transition.xml
<fade xmlns:android="http://schemas.android.com/apk/res/android" />
MainActvity.java
// 加載xml中的transition
Transition mFadeTransition =
TransitionInflater.from(this).
inflateTransition(R.transition.fade_transition);
也可以在代碼中創(chuàng)建
Transition mFadeTransition = new Fade();
創(chuàng)建多個transition(注:這個官方文檔中說要創(chuàng)建transitions文件夾,不過該路徑貌似有問題谓松,直接放在transition文件夾下即可)
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:transitionOrdering="sequential">
<fade android:fadingMode="fade_out" />
<changeBounds />
<fade android:fadingMode="fade_in" />
</transitionSet>
3. 應用Transition
使用TransitionManager.go()
TransitionManager.go(mEndingScene, mFadeTransition);
不使用Scene的情況下應用Transition
如果變化只是發(fā)生在當前的view hierarchy中星压,就沒必要創(chuàng)建一個scene。事實上鬼譬,你可以使用delayed transition來完成一個view hierarchy的兩種狀態(tài)變化娜膘。delayed transiton開始于當前view hierarchy的狀態(tài),并記錄下它的views的變化优质,等在系統(tǒng)重繪時來應用transition竣贪。創(chuàng)建步驟如下:
- 調用TransitionManager.beginDelayedTransition(final ViewGroup sceneRoot),sceneRoot的state會被保存
- 改變子view的狀態(tài)巩螃,比如添加或變大之類的演怎,transition會自動記錄變化
- 讓系統(tǒng)重繪,然后transition會自動從最初的狀態(tài)開始沿著新的狀態(tài)變更
// 1. Start recording changes to the view hierarchy
TransitionManager.beginDelayedTransition(mRootView, mFade);
// 2. Add the new TextView to the view hierarchy
mRootView.addView(mLabelText);
// 3. When the system redraws the screen to show this update,
// the framework will animate the addition as a fade in
自定義Transitions
- 繼承Transition類
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) {}
}
- 保存起始和結束的狀態(tài)值
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());
}
@Override
public void captureEndValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
...
}
- 重寫createAnimator() (optional)
使用限制
- 在SurfaceView上使用可能會不正常避乏,因為SurfaceView是通過非UI線程來更新界面的爷耀,應此可能與其他View不同步
- 某些特定的transition類型在Textureview上使用效果有問題
- AdapterView家族的類(如ListView)與tansition框架不兼容,使用會掛
- 如果你在TextView同時使用tansition和縮放動畫拍皮,TextView中的text會在縮放動畫完成前就pop到新的位置歹叮。為了避免此問題跑杭,避免同時使用