注:本文翻譯自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的代碼中,將視圖設(shè)置為你剛才創(chuàng)建的布局。也可以展示一個創(chuàng)建activity時默認(rèn)的fragment,下面的代碼展示了如何顯示默認(rèn)的卡牌的正面:
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)建一個方法來顯示卡牌的另一面,它做如下幾件事情:
設(shè)置你之前為fragment切換所創(chuàng)建的自定義動畫。
用新的fragment替換當(dāng)前顯示的fragment,并用你創(chuàng)建的自定義動畫來執(zhí)行這次動畫切換。
將之前顯示的fragment添加到回退棧中,所以當(dāng)用戶按下返回鍵時,卡片會翻轉(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ù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

