zoukankan      html  css  js  c++  java
  • 【Android Developers Training】 71. 显示翻牌动画

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

    原文链接:http://developer.android.com/training/animation/cardflip.html


    这一节课将向您展示如何用自定义的fragment动画来实现翻牌动画(Card Flip)。翻牌动画是在视图切换的时候以翻牌形式为过渡动画的效果,其如下所示:

    Card Flip动画

    如果你希望略过这部分内容直接看代码样例,可以直接下载样例代码,然后选择淡入淡出动画的例子。下面的文件是实现代码:

    • 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

    一). 创建动画执行器

    要创建翻牌动画,在“卡片”移出或者移入时,你需要两个动画执行器(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>

    二). 创建视图

    “卡片”的每一面是任何你希望的相互独立的内容,比如两屏的文字,两幅图片,或者任何视图的组合。接下来你就需要后面需要增加动画的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" />

    三). 创建Fragment

    为卡片的正反面创建fragment。这些类返回你之前在每个fragment中的onCreateView()方法中创建的布局。你可以在这些fragment的父activity(你期望显示卡牌的地方)创建这些fragment的实例。下面的代码展示了一个包含有fragment内部类的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);
            }
        }
    }

    四). 卡片翻转动画

    现在,你需要展示一个父activity中的fragment。要这么做,首先为你的activity创建布局。下面的例子创建了一个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的代码中,将视图设置为你刚才创建的布局。也可以展示一个创建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();
            }
        }
        ...
    }

    现在你已经有了卡牌的正面,你可以在某个时间通过卡牌反面的动画显示卡牌的背面。创建一个方法来显示卡牌的另一面,它做如下几件事情:

    设置你之前为fragment切换所创建的自定义动画。

    用新的fragment替换当前显示的fragment,并用你创建的自定义动画来执行这次动画切换。

    将之前显示的fragment添加到回退栈中,所以当用户按下返回键时,卡片会翻转回来。

    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();
    }
  • 相关阅读:
    调用组件的C++代码
    如何用C语言读写文件
    linux 常用命令总结(tsg)
    com.mysql.jdbc.MysqlDataTruncation: Data trunca...
    SpringMVC配置
    中文转换成Unicode编码 和 Unicode编码转换为中文
    在visual studio中运行C++心得
    博客园博客转至个人网站博客声明
    Seafile安装踩坑
    不要因为走得太远,而忘了自己的初心
  • 原文地址:https://www.cnblogs.com/jdneo/p/3566384.html
Copyright © 2011-2022 走看看