【Android Developers Training】 71. 显示翻牌

系统 1644 0

注:本文翻译自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();

}
      
    

【Android Developers Training】 71. 显示翻牌动画


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论