Android Transition框架介紹及使用教程

51CTO發表於2014-11-08

Android Transition框架允許我們對應用程式使用者介面當中的各類外觀變化加以配置。大家可以在應用程式螢幕內實現動畫式過渡、將每個階段定義為一種場景並控制應用程式如何從一種顯示場景過渡到另一種。

在今天的文章中,我們將構建一款簡單的應用程式、併為其製作一套動畫過渡效果。為了完成這項任務,大家需要涉及的內容包括在XML當中準備佈局與可繪製檔案、而後利用Java配置並應用這套過渡機制。我們將定義兩種場景,其中同樣的一組檢視專案將以不同方式排列在裝置螢幕之上。在大家使用Transition框架時,Android將自動完成兩種場景轉換過程中的動畫過渡效果。

1. 建立應用程式

第一步

作為教程的第一步,我們首先在自己選定的IDE中建立一款新的應用程式。大家至少需要使用SDK 19才能讓這些Transition類順利起效,因此如果打算讓其支援其它早期版本、我們還需要執行其它一些額外步驟。

首先為應用程式指定一個主Activity與佈局檔案,併為該佈局選擇start_layout.xml作為名稱。我們隨後還會新增其它佈局檔案,並利用Transition機制在不同顯示佈局之間進行轉換。下面幾幅截圖顯示了這一過程在Android Studio中的具體實現流程。

第二步

下面我們在Transition中準備一些可繪製圖形以資利用。我們將準備四個圓形圖案,每一個都採用不同的漸變顏色進行填充。在這款示例應用程式的可繪製資源目錄內,首先建立一個名為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>

以上程式碼構建出的是一個由漸變色填充而成的圓形圖案。而四個圖形在大小與樣式方面完全相同,僅僅在色彩上有所區別。當然,大家可能需要為不同畫素密度的裝置分別準備多種不同版本的圖形。利用以下程式碼建立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>

現在新增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應用在兩種佈局場景之內。

2. 建立佈局場景

第一步

接下來,我們要對將在幾種XML佈局之間進行過渡的兩類場景進行定義。首先是處理大家在建立應用程式時就已經新增完成的主佈局檔案,即start_layout.xml。將其開啟並切換到XML編輯標籤。利用以下程式碼使用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>

我們已經為該佈局新增了背景顏色與ID。這條ID的作用在於確保Android處理不同場景之間的過渡效果,大家還將在第二個場景中再次使用同樣的ID。當我們在兩個場景之間過渡時,Android會以動畫形式對各場景中擁有同樣ID的檢視進行轉換。如果二者不具備同樣的ID,那麼Android系統會將它們視為完全不同的專案、並單純以淡入或者淡出方式處理其過渡效果。

在RelativeLayout當中,為我們之前建立好的每個圖形建立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——我們建立的第二套佈局當然也是如此——外加onClick屬性。我們隨後將把這一方法新增到主Activity當中並在使用者點選任意圖形時啟動過渡流程。

現在我們將在IDE當中看到整套佈局的預覽圖,不過在某些情況下大家要真正在裝置或者模擬器上執行該應用才能看到其漸變以及/或者透明效果。這些圖形被排列在螢幕的四個邊角位置,具體效果如下圖所示。

第二步

我們建立的第一套佈局方案將顯示為過渡流程的起始狀態。現在讓我們為場景建立第二個佈局檔案,並將其作為過渡流程的結束狀態。在我們的應用程式佈局資源目錄中新增一個新檔案,將其命名為end_layout.xml。切換到文字編輯標籤並輸入以下程式碼:

<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>

現在讓我們花點時間審視以上佈局程式碼。除了各個圖形按鈕的位置之外,它與第一套佈局完全相同。每個圖形都從起始位置被移動到了其對角線處。過渡流程將因此而對各圖形進行位置互換,也就是將其引導至螢幕上的對角位置。

3. 不同場景之間進行過渡

第一步

現在我們已經對兩套佈局進行了定義,現在要做的就是利用過渡機制完成二者之間的移動流程。開啟應用程式中的主Activity類。大家將需要使用以下匯入語句:

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方法之前處,我們需要新增以下例項變數以應用該過渡機制:

//scenes to transition 
private Scene scene1, scene2; 
//transition to move between scenes 
private Transition transition; 
//flag to swap between scenes 
private boolean start;

第二步

現在讓我們為過渡做好準備,整個流程將在使用者點選任意圖形時正式開始。在onCreate中,我們要在IDE已經輸入的現有程式碼之後新增以下內容:

//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);

我們首先需要對基礎場景進行定義,也就是我們在兩個場景佈局檔案內為所包含佈局設定的ID。接下來,我們還需要定義作為過渡流程起始與結束狀態的兩個場景,為其指定佈局檔名稱以及所包含基礎場景。通過這種方式,Android將能夠根據我們的需要在兩個場景之間進行過渡、並將不同場景下具備相同ID的任意檢視元素作為同一物件加以處理,這樣場景切換時就能顯示出動畫式的變化效果。

接下來,我們定義作為過渡流程起始與結束狀態的兩個場景,仍然是在onCreate當中:

//create the two scenes 
scene1 = new Scene(baseLayout, startViews); 
scene2 = new Scene(baseLayout, endViews);

我們要將基礎佈局與相關場景佈局傳遞至每一個建構函式當中。現在我們已經可以在定義過渡流程時引用這些場景了。

第三步

下面我們作好執行過渡的準備,仍然是在onCreate當中:

//create transition, set properties 
transition = new AutoTransition(); 
transition.setDuration(5000); 
transition.setInterpolator(new AccelerateDecelerateInterpolator()); 

//initialize flag 
start=true;

Android提供了一系列過渡型別可供選擇,大家可以根據自己需要的場景變化方式採用其中的不同動畫效果。在今天的示例當中,我們選擇的是AutoTransition,因此Android會計算如何以兩種變化場景的屬性為基礎實現過渡。感興趣的朋友也可以點選此處檢視更多與Transition引用相關的選項。

我們為過渡流程設定了持續時間與內插程式。大家也可以根據需要為整套變化機制設定啟動延時。最後,我們通過初始化將布林標記設定為true。為了簡便起見,我們將採取點選任意圖形來啟用場景切換的方式,但這只是為了演示示例所具備的實際功能。

第四步

大家一定還記得,我們在建立佈局XML檔案時已經將onClick屬性新增到圖形按鈕當中。現在我們要將該方法新增到Activity內:

public void changeScene(View v){ 

    //check flag 
    if(start) { 
        TransitionManager.go(scene2, transition); 
        start=false; 
    } 
    else { 
        TransitionManager.go(scene1, transition); 
        start=true; 
    } 
}

我們利用Activity實現從當前場景向另一套場景的過渡,其中布林標記會持續追蹤我們當前正在使用的場景型別。我們還指定了此前已經建立完成的Transition物件,旨在保證切換的執行過程與預期效果相匹配。

現在大家應該已經可以執行自己的應用程式,並在點選任意圖形時檢視到整個過渡流程。每當我們執行點選操作時,過渡流程就會將各個圖形緩慢移動到螢幕上的對角線位置,再次點選則可使其迴歸原位。

內容總結

在今天的文章中,我們事實上還只是初步瞭解了自己能夠利用Android Transition框架實現怎樣的設計方案與過渡效果。要在自己的應用程式中引入更多過渡機制,大家可以點選此處檢視TransitionManager類當中的其它方法,其中包括beginDelayedTransition與transitionTo。此外,大家也不妨嘗試利用TransitionSet將多種過渡機制結合在一起,例如同時使用來自不同過渡機制的漸變與移動效果。根據過渡機制複雜程度的不同,大家可能還需要用到TransitionValues類,它能夠提供與對應過渡相關的資料值引用能力。如果各位還想了解更多與場景處理相關的技術手段,也可以點選此處檢視Scene類的相關說明。

相關文章