Android技術分享| Activity 過渡動畫 — 讓切換更加炫酷

語言: CN / TW / HK

介紹

在 android5.0 以上版本中,google 為我們提供了幾種 activity 切換的過渡動畫,目的是為了讓 activity 切換轉場更加美觀,而在 android5.0 之前的 activity 切換顯得生硬。雖然可以自定義給 activity 增添動畫效果,但是效果也不盡如意。而 androi5.x 提供的切換動畫就顯得非常自然,而且容易使用。

現在我們來看看 androi5.x 提供的動畫效果圖:

在這裡插入圖片描述

Activity過渡動畫

在 androi5.x 中,為 activity 提供了三中動畫效果,分別是:

  • explode(分解)
  • slide(滑進滑出)
  • fade(淡入淡出)

這三種都是 activity 的切換動畫效果,除了這三種以外,我們看如上動態圖中的 “共享元素” ,它其實也是一種轉場動畫,只不過這種需要一定的條件才能夠使用。比如: activity1 和 activity2 中有兩個一模一樣的內容,從 activity1 跳轉到 activity2 時我們才運用共享元素的動畫效果,達到更加的 ui 體驗。

下面我們來具體學習和實現一下這幾種過渡動畫。

一、explode(分解)

效果圖:

在這裡插入圖片描述

explode 從螢幕中間進或者出,然後將檢視移動至最後位置,達到動畫的效果。

二、slide(滑動)

效果圖:

在這裡插入圖片描述

slide 是從螢幕邊緣進出,同理通過移動檢視形成動畫。

三、fade(淡入淡出)

效果圖:

在這裡插入圖片描述

fade 則是通過改變檢視的透明度來達到動畫效果。

如何使用

我們知道開啟一個 activity 只需 startActivity(); 即可,更多的是,我們要想加入過渡動畫,也只需要在 startActivity(); 中傳入需要的引數即可。

  • 第一步:

例如,我要從 MainActivity 中啟動 AnimationActivity,只需要在 MainActivity 中 startActivity(); 傳入引數即可,程式碼如下:

java startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

  • 第二步:

在 AnimationActivity 中的 setContentView(); 方法前加入一行程式碼:

java //在需要啟動的 activity 中開啟動畫的特徵 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

或者,在 AnimationActivity 中設定如下 style,並引用到 AnimationActivity 即可。

xml <item name="android:windowContentTransitions">true</item>

  • 第三步:

在 AnimationActivity 中設定要應用的動畫效果,如上面介紹的,效果有三種。然後選擇任意一種即可,程式碼如下:

java getWindow().setEnterTransition(new Explode()); getWindow().setEnterTransition(new Slide()); getWindow().setEnterTransition(new Fade());

上面設定的是進入 activity 的動畫,也可以設定退出 activity 的動畫,程式碼如下:

java getWindow().setExitTransition(new Explode()); getWindow().setExitTransition(new Slide()); getWindow().setExitTransition(new Fade());

共享元素動畫效果

通過上面這三個步驟,我相信你一定可以實現簡單的 activity 過渡動畫了,然後接下來介紹的是 activity 共享元素的動畫效果,這裡會稍微難一點。我就拿我的例子一部分來舉例子,這樣顯得更加容易理解。

例如,我的例子中兩個頁面都有一個同樣內容的 textview ,所以要使其得到共享。

```xml

<android.support.v7.widget.AppCompatTextView
    android:id="@+id/tv_shared_element"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:layout_marginTop="56dp"
    android:layout_marginBottom="72dp"
    android:gravity="center_horizontal"
    android:text="@string/app_txt"
    android:textColor="#323232"
    android:textSize="18sp"
    android:transitionName="shared element"
    tools:ignore="UnusedAttribute" />

```

注意:我們必須為兩個頁面的共同元素(textview)設定一個屬性:

xml android:transitionName="shared element"

並且必須保證兩個 textview 的 transitionName 設定的內容一致,否者將無法達到共享元素的動畫效果。

最後的關鍵一步:更改 startActivity(); 引數內容,因為我們設定了共享元素,所以到進行指定,這樣 startActivity 時才能夠找到目標,所以啟動 activity 的程式碼因改為這樣:

java //這裡的 sharedElementName 必須與 xml 檔案中設定的值一致,否則無法共享 // tvSharedElement 表示要參與共享的 view startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, tvSharedElement, "shared element").toBundle());

如果你的兩個 activity 中有兩個及以上的內容需要共享元素動畫時,你只需要修改程式碼為:

java startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, Pair.create((View) tvSharedElement, "shared element")) .toBundle());

這裡通過 Pair.create(view,"shared name");來傳入需要共享的元素。

好了,本篇關於 android5.x 提供的幾種過渡動畫效果就展示完了,雖然過渡動畫效果很漂亮,但是也要合理的運用,也不能每一個 activity 都設定過渡動畫。那麼,如上動態圖演示的一樣,本案例關鍵程式碼將在下面貼出:

案例程式碼

MainActivity 程式碼如下:

```java package com.xww.activityanims;

import android.annotation.SuppressLint; import android.app.ActivityOptions; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.AppCompatButton; import android.support.v7.widget.AppCompatTextView; import android.util.Pair; import android.view.View;

import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick;

@SuppressLint("NewApi") public class MainActivity extends AppCompatActivity {

@BindView(R.id.btn_explode)
AppCompatButton btnExplode;
@BindView(R.id.btn_slide)
AppCompatButton btnSlide;
@BindView(R.id.btn_fade)
AppCompatButton btnFade;
@BindView(R.id.tv_shared_element)
AppCompatTextView tvSharedElement;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
}

@OnClick(R.id.btn_explode)
void onExplodeClick() {
    Intent intent = new Intent(this, AnimationsActivity.class);
    startActivityWithAnimation(intent, "explode");
}

@OnClick(R.id.btn_slide)
void onSlideClick() {
    Intent intent = new Intent(this, AnimationsActivity.class);
    startActivityWithAnimation(intent, "slide");
}

@OnClick(R.id.btn_fade)
void onFadeClick() {
    Intent intent = new Intent(this, AnimationsActivity.class);
    startActivityWithAnimation(intent, "fade");
}

private void startActivityWithAnimation(Intent intent, String animType) {
    intent.putExtra("anim", animType);
    //這裡的 sharedElementName 必須與 xml 檔案中設定的值一致,否則無法共享
    // tvSharedElement 表示要參與共享的 view

// startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, tvSharedElement, // "shared element").toBundle()); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, Pair.create((View) tvSharedElement, "shared element")) .toBundle()); } } ```

接著是 AnimationsActivity 的程式碼,這是一個開啟動畫的 Activity ,程式碼如下:

```java package com.xww.activityanims;

import android.annotation.SuppressLint; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.AppCompatTextView; import android.transition.Explode; import android.transition.Fade; import android.transition.Slide; import android.view.Window;

import butterknife.BindView; import butterknife.ButterKnife;

@SuppressLint("NewApi") public class AnimationsActivity extends AppCompatActivity {

@BindView(R.id.tv_anim_type)
AppCompatTextView tvAnimType;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //在需要啟動的 activity 中開啟動畫的特徵
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

    setContentView(R.layout.activity_animations);
    ButterKnife.bind(this);

    setEnterAnim();
}

@SuppressWarnings("ConstantConditions")
private void setEnterAnim() {
    final String animType = (String) getIntent().getExtras().get("anim");
    tvAnimType.setText(animType);

    switch (animType) {
        case "explode":
            getWindow().setEnterTransition(new Explode());
            break;
        case "slide":
            getWindow().setEnterTransition(new Slide());
            break;
        case "fade":
            getWindow().setEnterTransition(new Fade());
            break;
    }
}

} ```

AnimationsActivity 佈局檔案如下:

```xml

<android.support.v7.widget.ContentFrameLayout
    android:id="@+id/frame"
    android:layout_width="match_parent"
    android:layout_height="280dp"
    android:background="#ff3312">

    <android.support.v7.widget.AppCompatTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="http://blog.csdn.net/smile_Running"
        android:textColor="#ffffff"
        android:textSize="20sp"
        tools:ignore="HardcodedText" />

</android.support.v7.widget.ContentFrameLayout>

<!-- anchor 屬性必須在 CoordinatorLayout 下一級才能生效 -->
<android.support.design.widget.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_person_add_black_24dp"
    app:elevation="8dp"
    app:layout_anchor="@id/frame"
    app:layout_anchorGravity="bottom|right" />

<android.support.design.widget.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_sentiment_satisfied_black_24dp"
    app:elevation="8dp"
    app:layout_anchor="@id/frame"
    app:layout_anchorGravity="bottom|left" />

<android.support.v7.widget.CardView
    android:layout_width="220dp"
    android:layout_height="120dp"
    app:cardBackgroundColor="#ffdd55"
    app:cardCornerRadius="24dp"
    app:cardElevation="8dp"
    app:layout_anchor="@id/frame"
    app:layout_anchorGravity="bottom|center_horizontal">

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/tv_anim_type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="animations"
        android:textColor="#ffffff"
        android:textSize="25sp"
        tools:ignore="HardcodedText" />
</android.support.v7.widget.CardView>

<android.support.v7.widget.AppCompatTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:layout_marginBottom="72dp"
    android:gravity="center_horizontal"
    android:text="@string/app_txt"
    android:textColor="#323232"
    android:textSize="18sp"
    android:transitionName="shared element"
    tools:ignore="UnusedAttribute" />

```

讓我們的 Activity 的切換更加炫酷起來吧!

在這裡插入圖片描述