移動開發(fā)指南:Android Transition框架介紹
譯文【51CTO譯文】Android Transition框架允許我們對應(yīng)用程序用戶界面當(dāng)中的各類外觀變化加以配置。大家可以在應(yīng)用程序屏幕內(nèi)實現(xiàn)動畫式過渡、將每個階段定義為一種場景并控制應(yīng)用程序如何從一種顯示場景過渡到另一種。
在今天的文章中,我們將構(gòu)建一款簡單的應(yīng)用程序、并為其制作一套動畫過渡效果。為了完成這項任務(wù),大家需要涉及的內(nèi)容包括在XML當(dāng)中準(zhǔn)備布局與可繪制文件、而后利用Java配置并應(yīng)用這套過渡機制。我們將定義兩種場景,其中同樣的一組視圖項目將以不同方式排列在設(shè)備屏幕之上。在大家使用Transition框架時,Android將自動完成兩種場景轉(zhuǎn)換過程中的動畫過渡效果。
1. 創(chuàng)建應(yīng)用程序
***步
作為教程的***步,我們首先在自己選定的IDE中創(chuàng)建一款新的應(yīng)用程序。大家至少需要使用SDK 19才能讓這些Transition類順利起效,因此如果打算讓其支持其它早期版本、我們還需要執(zhí)行其它一些額外步驟。
首先為應(yīng)用程序指定一個主Activity與布局文件,并為該布局選擇start_layout.xml作為名稱。我們隨后還會添加其它布局文件,并利用Transition機制在不同顯示布局之間進(jìn)行轉(zhuǎn)換。下面幾幅截圖顯示了這一過程在Android Studio中的具體實現(xiàn)流程。
第二步
下面我們在Transition中準(zhǔn)備一些可繪制圖形以資利用。我們將準(zhǔn)備四個圓形圖案,每一個都采用不同的漸變顏色進(jìn)行填充。在這款示例應(yīng)用程序的可繪制資源目錄內(nèi),首先創(chuàng)建一個名為shape1.xml的新文件。通過以下代碼添加圖形:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:dither="true"
- android:shape="oval" >
- <gradient
- android:endColor="#66ff0000"
- android:gradientRadius="150"
- android:startColor="#ffffcc00"
- android:type="radial"
- android:useLevel="false" />
- <size
- android:height="100dp"
- android:width="100dp" />
- </shape>
以上代碼構(gòu)建出的是一個由漸變色填充而成的圓形圖案。而四個圖形在大小與樣式方面完全相同,僅僅在色彩上有所區(qū)別。當(dāng)然,大家可能需要為不同像素密度的設(shè)備分別準(zhǔn)備多種不同版本的圖形。利用以下代碼創(chuàng)建shape2.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:dither="true"
- android:shape="oval" >
- <gradient
- android:endColor="#66ffcc00"
- android:gradientRadius="150"
- android:startColor="#ff00ff00"
- android:type="radial"
- android:useLevel="false" />
- <size
- android:height="100dp"
- android:width="100dp" />
- </shape>
現(xiàn)在添加shape3.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:dither="true"
- android:shape="oval" >
- <gradient
- android:endColor="#6600ff00"
- android:gradientRadius="150"
- android:startColor="#ff0000ff"
- android:type="radial"
- android:useLevel="false" />
- <size
- android:height="100dp"
- android:width="100dp" />
- </shape>
***添加shape4.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:dither="true"
- android:shape="oval" >
- <gradient
- android:endColor="#660000ff"
- android:gradientRadius="150"
- android:startColor="#ffff0000"
- android:type="radial"
- android:useLevel="false" />
- <size
- android:height="100dp"
- android:width="100dp" />
- </shape>
我們將把這些圖形作為ImageButtons應(yīng)用在兩種布局場景之內(nèi)。
#p#
2. 創(chuàng)建布局場景
***步
接下來,我們要對將在幾種XML布局之間進(jìn)行過渡的兩類場景進(jìn)行定義。首先是處理大家在創(chuàng)建應(yīng)用程序時就已經(jīng)添加完成的主布局文件,即start_layout.xml。將其打開并切換到XML編輯標(biāo)簽。利用以下代碼使用RelativeLayout:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#ff000000"
- android:id="@+id/base"
- tools:context=".TransitionsActivity">
- </RelativeLayout>
我們已經(jīng)為該布局添加了背景顏色與ID。這條ID的作用在于確保Android處理不同場景之間的過渡效果,大家還將在第二個場景中再次使用同樣的ID。當(dāng)我們在兩個場景之間過渡時,Android會以動畫形式對各場景中擁有同樣ID的視圖進(jìn)行轉(zhuǎn)換。如果二者不具備同樣的ID,那么Android系統(tǒng)會將它們視為完全不同的項目、并單純以淡入或者淡出方式處理其過渡效果。
在RelativeLayout當(dāng)中,為我們之前創(chuàng)建好的每個圖形創(chuàng)建ImageButton:
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/btn1"
- android:src="@drawable/shape1"
- android:background="#00000000"
- android:contentDescription="shape"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:onClick="changeScene"/>
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/btn2"
- android:src="@drawable/shape2"
- android:background="#00000000"
- android:contentDescription="shape"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- android:onClick="changeScene"/>
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/btn3"
- android:src="@drawable/shape3"
- android:background="#00000000"
- android:contentDescription="shape"
- android:layout_alignParentLeft="true"
- android:layout_alignParentBottom="true"
- android:onClick="changeScene"/>
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/btn4"
- android:src="@drawable/shape4"
- android:background="#00000000"
- android:contentDescription="shape"
- android:layout_alignParentRight="true"
- android:layout_alignParentBottom="true"
- android:onClick="changeScene"/>
需要注意的是,每一個圖形按鈕都擁有自己的ID——我們創(chuàng)建的第二套布局當(dāng)然也是如此——外加onClick屬性。我們隨后將把這一方法添加到主Activity當(dāng)中并在用戶點擊任意圖形時啟動過渡流程。
現(xiàn)在我們將在IDE當(dāng)中看到整套布局的預(yù)覽圖,不過在某些情況下大家要真正在設(shè)備或者模擬器上運行該應(yīng)用才能看到其漸變以及/或者透明效果。這些圖形被排列在屏幕的四個邊角位置,具體效果如下圖所示。
第二步
我們創(chuàng)建的***套布局方案將顯示為過渡流程的起始狀態(tài)?,F(xiàn)在讓我們?yōu)閳鼍皠?chuàng)建第二個布局文件,并將其作為過渡流程的結(jié)束狀態(tài)。在我們的應(yīng)用程序布局資源目錄中添加一個新文件,將其命名為end_layout.xml。切換到文本編輯標(biāo)簽并輸入以下代碼:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#ff000000"
- android:id="@+id/base"
- tools:context=".TransitionsActivity">
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/btn1"
- android:src="@drawable/shape1"
- android:background="#00000000"
- android:contentDescription="shape"
- android:layout_alignParentRight="true"
- android:layout_alignParentBottom="true"
- android:onClick="changeScene"/>
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/btn2"
- android:src="@drawable/shape2"
- android:background="#00000000"
- android:contentDescription="shape"
- android:layout_alignParentLeft="true"
- android:layout_alignParentBottom="true"
- android:onClick="changeScene"/>
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/btn3"
- android:src="@drawable/shape3"
- android:background="#00000000"
- android:contentDescription="shape"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- android:onClick="changeScene"/>
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/btn4"
- android:src="@drawable/shape4"
- android:background="#00000000"
- android:contentDescription="shape"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:onClick="changeScene"/>
- </RelativeLayout>
現(xiàn)在讓我們花點時間審視以上布局代碼。除了各個圖形按鈕的位置之外,它與***套布局完全相同。每個圖形都從起始位置被移動到了其對角線處。過渡流程將因此而對各圖形進(jìn)行位置互換,也就是將其引導(dǎo)至屏幕上的對角位置。
#p#
3. 不同場景之間進(jìn)行過渡
***步
現(xiàn)在我們已經(jīng)對兩套布局進(jìn)行了定義,現(xiàn)在要做的就是利用過渡機制完成二者之間的移動流程。打開應(yīng)用程序中的主Activity類。大家將需要使用以下導(dǎo)入語句:
- import android.transition.AutoTransition;
- import android.transition.Scene;
- import android.transition.Transition;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.animation.AccelerateDecelerateInterpolator;
- import android.widget.RelativeLayout;
- import android.transition.TransitionManager;
在Activity類聲明中、onCreate方法之前處,我們需要添加以下實例變量以應(yīng)用該過渡機制:
- //scenes to transition
- private Scene scene1, scene2;
- //transition to move between scenes
- private Transition transition;
- //flag to swap between scenes
- private boolean start;
第二步
現(xiàn)在讓我們?yōu)檫^渡做好準(zhǔn)備,整個流程將在用戶點擊任意圖形時正式開始。在onCreate中,我們要在IDE已經(jīng)輸入的現(xiàn)有代碼之后添加以下內(nèi)容:
- //get the layout ID
- RelativeLayout baseLayout = (RelativeLayout)findViewById(R.id.base);
- //first scene
- ViewGroup startViews = (ViewGroup)getLayoutInflater()
- .inflate(R.layout.start_layout, baseLayout, false);
- //second scene
- ViewGroup endViews = (ViewGroup)getLayoutInflater()
- .inflate(R.layout.end_layout, baseLayout, false);
我們首先需要對基礎(chǔ)場景進(jìn)行定義,也就是我們在兩個場景布局文件內(nèi)為所包含布局設(shè)定的ID。接下來,我們還需要定義作為過渡流程起始與結(jié)束狀態(tài)的兩個場景,為其指定布局文件名稱以及所包含基礎(chǔ)場景。通過這種方式,Android將能夠根據(jù)我們的需要在兩個場景之間進(jìn)行過渡、并將不同場景下具備相同ID的任意視圖元素作為同一對象加以處理,這樣場景切換時就能顯示出動畫式的變化效果。
接下來,我們定義作為過渡流程起始與結(jié)束狀態(tài)的兩個場景,仍然是在onCreate當(dāng)中:
- //create the two scenes
- scene1 = new Scene(baseLayout, startViews);
- scene2 = new Scene(baseLayout, endViews);
我們要將基礎(chǔ)布局與相關(guān)場景布局傳遞至每一個構(gòu)造函數(shù)當(dāng)中?,F(xiàn)在我們已經(jīng)可以在定義過渡流程時引用這些場景了。
第三步
下面我們作好執(zhí)行過渡的準(zhǔn)備,仍然是在onCreate當(dāng)中:
- //create transition, set properties
- transition = new AutoTransition();
- transition.setDuration(5000);
- transition.setInterpolator(new AccelerateDecelerateInterpolator());
- //initialize flag
- start=true;
Android提供了一系列過渡類型可供選擇,大家可以根據(jù)自己需要的場景變化方式采用其中的不同動畫效果。在今天的示例當(dāng)中,我們選擇的是AutoTransition,因此Android會計算如何以兩種變化場景的屬性為基礎(chǔ)實現(xiàn)過渡。感興趣的朋友也可以點擊此處查看更多與Transition引用相關(guān)的選項。
我們?yōu)檫^渡流程設(shè)置了持續(xù)時間與內(nèi)插程序。大家也可以根據(jù)需要為整套變化機制設(shè)定啟動延時。***,我們通過初始化將布爾標(biāo)記設(shè)定為true。為了簡便起見,我們將采取點擊任意圖形來激活場景切換的方式,但這只是為了演示示例所具備的實際功能。
第四步
大家一定還記得,我們在創(chuàng)建布局XML文件時已經(jīng)將onClick屬性添加到圖形按鈕當(dāng)中?,F(xiàn)在我們要將該方法添加到Activity內(nèi):
- public void changeScene(View v){
- //check flag
- if(start) {
- TransitionManager.go(scene2, transition);
- start=false;
- }
- else {
- TransitionManager.go(scene1, transition);
- start=true;
- }
- }
我們利用Activity實現(xiàn)從當(dāng)前場景向另一套場景的過渡,其中布爾標(biāo)記會持續(xù)追蹤我們當(dāng)前正在使用的場景類型。我們還指定了此前已經(jīng)創(chuàng)建完成的Transition對象,旨在保證切換的執(zhí)行過程與預(yù)期效果相匹配。
現(xiàn)在大家應(yīng)該已經(jīng)可以運行自己的應(yīng)用程序,并在點擊任意圖形時查看到整個過渡流程。每當(dāng)我們執(zhí)行點擊操作時,過渡流程就會將各個圖形緩慢移動到屏幕上的對角線位置,再次點擊則可使其回歸原位。
內(nèi)容總結(jié)
在今天的文章中,我們事實上還只是初步了解了自己能夠利用Android Transition框架實現(xiàn)怎樣的設(shè)計方案與過渡效果。要在自己的應(yīng)用程序中引入更多過渡機制,大家可以點擊此處查看TransitionManager類當(dāng)中的其它方法,其中包括beginDelayedTransition與transitionTo。此外,大家也不妨嘗試?yán)?a target="_blank">TransitionSet將多種過渡機制結(jié)合在一起,例如同時使用來自不同過渡機制的漸變與移動效果。根據(jù)過渡機制復(fù)雜程度的不同,大家可能還需要用到TransitionValues類,它能夠提供與對應(yīng)過渡相關(guān)的數(shù)據(jù)值引用能力。如果各位還想了解更多與場景處理相關(guān)的技術(shù)手段,也可以點擊此處查看Scene類的相關(guān)說明。
原文鏈接:An Introduction to Android Transitions
核子可樂譯