Android官網培訓課:顯示卡片翻轉動畫

本節課講解如何以定製的fragment動畫來實現卡片翻轉動畫。

創建animator


創建卡片翻轉的動畫。你需要兩個animator,用於卡片的正面向左向外翻轉,然後從左向內翻轉。你同意需要兩個animator,用於卡片的北面從右向內翻轉,然後向右向外翻轉。

card_flip_left_in.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 在旋轉之前,立即將透明度alpha設爲0-->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- 旋轉. -->
    <objectAnimator
        android:valueFrom="-180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- 旋轉過程中(見 startOffset), 設置透明度alpha 爲 1. -->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

card_flip_left_out.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 旋轉. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- 旋轉過程中 (見startOffset), 設置透明度alpha 爲 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>
    

card_flip_right_in.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 在旋轉前,立即將透明度alpha設爲0 -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- 旋轉. -->
    <objectAnimator
        android:valueFrom="180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!--旋轉過程中 (見startOffset), 把透明度alpha設爲 1. -->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />

card_flip_right_out.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 旋轉. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="-180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- 旋轉過程中 (見startOffset), 設置 透明度alpha 爲 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

創建view


"卡片"的每一面是一個獨立的layout佈局,能夠裝下你想放置的任何內容,比如說兩屏文字,或者兩張圖片,或者任何view的組合。然後你可以在要翻轉的fragment中使用這兩個定義好的layout佈局。下面的layout佈局創建了卡片的一面,用於顯示文字。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#a6c"
    android:padding="16dp"
    android:gravity="bottom">

    <TextView android:id="@android:id/text1"
        style="?android:textAppearanceLarge"
        android:textStyle="bold"
        android:textColor="#fff"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/card_back_title" />

    <TextView style="?android:textAppearanceSmall"
        android:textAllCaps="true"
        android:textColor="#80ffffff"
        android:textStyle="bold"
        android:lineSpacingMultiplier="1.2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/card_back_description" />

</LinearLayout>

卡片的另一面顯示一個ImageView:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/image1"
    android:scaleType="centerCrop"
    android:contentDescription="@string/description_image_1" />

創建fragment


爲卡片的正面和背面創建fragment類。這兩個類在其各自的onCreateView()方法中返回你剛剛在前面創建的佈局。當你想展示卡片時,你就可以在父activity中創建該fragment的實例。下面的例子在父activity中創建fragment內部類。

public class CardFlipActivity extends Activity {
    ...
    /**
     * 代表卡片正面的fragment
     */
    public class CardFrontFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_card_front, container, false);
        }
    }

    /**
     * 代表卡片背面的fragment
     */
    public class CardBackFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_card_back, container, false);
        }
    }
}

卡片翻轉動畫


現在你需要在一個父activity內部顯示fragment。爲了做到這一點,首先創建你的activity的layout。下面的例子就是一個FrameLayout,在運行時將其添加到fragment中。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

在activity代碼中,把content view設置爲你剛剛創建的layout。在activity創建時顯示一個默認的fragment是個好的辦法,所以下面示例中在activity中默認顯示卡片的正面。

public class CardFlipActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity_card_flip);

        if (savedInstanceState == null) {
            getFragmentManager()
                    .beginTransaction()
                    .add(R.id.container, new CardFrontFragment())
                    .commit();
        }
    }
    ...
}

現在默認顯示的是卡片的正面了,你可以在適當的時間以翻轉動畫的形式顯示卡片的背面。創建一個方法來顯示卡片的另一面,需要做下面幾個事情:

  • 設置先前創建的fragment轉換的定製性動畫。
  • 用一個新的fragment替換當前顯示的fragment,並且用先前創建的定製動畫來處理這一事件。
  • 把先前顯示的fragment添加到fragment回退棧中,這養當用戶按下回退鍵,卡片會翻轉回去。
private void flipCard() {
    if (mShowingBack) {
        getFragmentManager().popBackStack();
        return;
    }

    // 翻向背面.

    mShowingBack = true;

    // 創建並提交一個fragment事務,添加卡片背面的fragment,使用定製動畫,使其成爲fragment manager的回退棧的一部分。

    getFragmentManager()
            .beginTransaction()

            // 用代表轉向卡片背面和轉向卡片正面的animator資源取代默認的fragment動畫。
            .setCustomAnimations(
                    R.animator.card_flip_right_in, R.animator.card_flip_right_out,
                    R.animator.card_flip_left_in, R.animator.card_flip_left_out)

            // 用代表下一頁的fragment(indicated by the just-incremented currentPage variable)取代當前正在container view中顯示的fragment。
            .replace(R.id.container, new CardBackFragment())

            // 把該事務提交到回退棧,當用戶按回退鍵時返回到卡片正面。
            .addToBackStack(null)

            // 提交事務.
            .commit();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章