注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術(shù)一般,由于喜愛安卓而產(chǎn)生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/animation/cardflip.html
這一節(jié)課將向您展示如何用自定義的fragment動畫來實現(xiàn)翻牌動畫(Card Flip)。翻牌動畫是在視圖切換的時候以翻牌形式為過渡動畫的效果,其如下所示:
如果你希望略過這部分內(nèi)容直接看代碼樣例,可以直接 下載 樣例代碼,然后選擇淡入淡出動畫的例子。下面的文件是實現(xiàn)代碼:
-
src/CardFlipActivity.java
-
animator/card_flip_right_in.xml
-
animator/card_flip_right_out.xml
-
animator/card_flip_left_in.xml
-
animator/card_flip_left_out.xml
-
layout/fragment_card_back.xml
-
layout/fragment_card_front.xml
一). 創(chuàng)建動畫執(zhí)行器
要創(chuàng)建翻牌動畫,在“卡片”移出或者移入時,你需要兩個動畫執(zhí)行器(Animator)。
card_flip_left_in.xml
< set xmlns:android ="http://schemas.android.com/apk/res/android" > <!-- Before rotating, immediately set the alpha to 0. --> < objectAnimator android:valueFrom ="1.0" android:valueTo ="0.0" android:propertyName ="alpha" android:duration ="0" /> <!-- Rotate. --> < objectAnimator android:valueFrom ="-180" android:valueTo ="0" android:propertyName ="rotationY" android:interpolator ="@android:interpolator/accelerate_decelerate" android:duration ="@integer/card_flip_time_full" /> <!-- Half-way through the rotation (see startOffset), set the alpha to 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" > <!-- Rotate. --> < objectAnimator android:valueFrom ="0" android:valueTo ="180" android:propertyName ="rotationY" android:interpolator ="@android:interpolator/accelerate_decelerate" android:duration ="@integer/card_flip_time_full" /> <!-- Half-way through the rotation (see startOffset), set the alpha to 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" > <!-- Before rotating, immediately set the alpha to 0. --> < objectAnimator android:valueFrom ="1.0" android:valueTo ="0.0" android:propertyName ="alpha" android:duration ="0" /> <!-- Rotate. --> < objectAnimator android:valueFrom ="180" android:valueTo ="0" android:propertyName ="rotationY" android:interpolator ="@android:interpolator/accelerate_decelerate" android:duration ="@integer/card_flip_time_full" /> <!-- Half-way through the rotation (see startOffset), set the alpha to 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" > <!-- Rotate. --> < objectAnimator android:valueFrom ="0" android:valueTo ="-180" android:propertyName ="rotationY" android:interpolator ="@android:interpolator/accelerate_decelerate" android:duration ="@integer/card_flip_time_full" /> <!-- Half-way through the rotation (see startOffset), set the alpha to 0. --> < objectAnimator android:valueFrom ="1.0" android:valueTo ="0.0" android:propertyName ="alpha" android:startOffset ="@integer/card_flip_time_half" android:duration ="1" /> </ set >
二). 創(chuàng)建視圖
“卡片”的每一面是任何你希望的相互獨立的內(nèi)容,比如兩屏的文字,兩幅圖片,或者任何視圖的組合。接下來你就需要后面需要增加動畫的fragment的兩個布局。下面卡片其中一面的布局:
< 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 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" />
三). 創(chuàng)建Fragment
為卡片的正反面創(chuàng)建fragment。這些類返回你之前在每個fragment中的
onCreateView()
方法中創(chuàng)建的布局。你可以在這些
fragment
的父
activity
(你期望顯示卡牌的地方)創(chuàng)建這些
fragment
的實例。下面的代碼展示了一個包含有
fragment
內(nèi)部類的
activity
類:
public class CardFlipActivity extends Activity { ... /** * A fragment representing the front of the card. */ 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 ); } } /** * A fragment representing the back of the card. */ 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 ); } } }
四). 卡片翻轉(zhuǎn)動畫
現(xiàn)在,你需要展示一個父activity中的fragment。要這么做,首先為你的activity創(chuàng)建布局。下面的例子創(chuàng)建了一個 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的代碼中,將視圖設置為你剛才創(chuàng)建的布局。也可以展示一個創(chuàng)建activity時默認的fragment,下面的代碼展示了如何顯示默認的卡牌的正面:
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(); } } ... }
現(xiàn)在你已經(jīng)有了卡牌的正面,你可以在某個時間通過卡牌反面的動畫顯示卡牌的背面。創(chuàng)建一個方法來顯示卡牌的另一面,它做如下幾件事情:
設置你之前為fragment切換所創(chuàng)建的自定義動畫。
用新的fragment替換當前顯示的fragment,并用你創(chuàng)建的自定義動畫來執(zhí)行這次動畫切換。
將之前顯示的fragment添加到回退棧中,所以當用戶按下返回鍵時,卡片會翻轉(zhuǎn)回來。
private void flipCard() { if (mShowingBack) { getFragmentManager().popBackStack(); return ; } // Flip to the back. mShowingBack = true ; // Create and commit a new fragment transaction that adds the fragment for the back of // the card, uses custom animations, and is part of the fragment manager's back stack. getFragmentManager() .beginTransaction() // Replace the default fragment animations with animator resources representing // rotations when switching to the back of the card, as well as animator // resources representing rotations when flipping back to the front (e.g. when // the system Back button is pressed). .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) // Replace any fragments currently in the container view with a fragment // representing the next page (indicated by the just-incremented currentPage // variable). .replace(R.id.container, new CardBackFragment()) // Add this transaction to the back stack, allowing users to press Back // to get to the front of the card. .addToBackStack( null ) // Commit the transaction. .commit(); }
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
