文档章节

android-卡片旋转特效

o
 osc_1ee7cxmx
发布于 2018/08/06 15:00
字数 1341
阅读 10
收藏 0

精选30+云产品,助力企业轻松上云!>>>

 直接看图:

 

实现此功能,会用到属性动画;

但是具体做起来,有两种途径:

1)纯java代码来写:

  1 package com.example.cardrotation;
  2 
  3 import android.animation.Animator;
  4 import android.animation.AnimatorListenerAdapter;
  5 import android.animation.AnimatorSet;
  6 import android.animation.ObjectAnimator;
  7 import android.os.Bundle;
  8 import android.support.v7.app.AppCompatActivity;
  9 import android.view.View;
 10 import android.widget.FrameLayout;
 11 
 12 /**
 13  * 旋转卡片特效
 14  * 第1种写法
 15  * <p>
 16  * 用纯java代码来写动画特效以及 执行动画
 17  */
 18 public class MainActivity2 extends AppCompatActivity {
 19 
 20     private FrameLayout mFlCardBack, mFlCardFront, mFlContainer;
 21 
 22     @Override
 23     protected void onCreate(Bundle savedInstanceState) {
 24         super.onCreate(savedInstanceState);
 25         setContentView(R.layout.activity_main);
 26 
 27         mFlCardBack = findViewById(R.id.fl_back);
 28         mFlCardFront = findViewById(R.id.fl_front);
 29         mFlContainer = findViewById(R.id.main_fl_container);
 30         mFlContainer.setOnClickListener(new View.OnClickListener() {
 31             @Override
 32             public void onClick(View v) {
 33                 flipCard();
 34             }
 35         });
 36 
 37         initAnimatorSet();
 38         setCameraDistance(); // 设置镜头距离
 39     }
 40 
 41     // 改变视角距离, 贴近屏幕,这个必须设置,因为如果不这么做,沿着Y轴旋转的过程中有可能产生超出屏幕的3D效果。
 42     private void setCameraDistance() {
 43         int distance = 16000;
 44         float scale = getResources().getDisplayMetrics().density * distance;
 45         mFlCardFront.setCameraDistance(scale);
 46         mFlCardBack.setCameraDistance(scale);
 47     }
 48 
 49     private boolean mIsShowBack = false;
 50 
 51     // 翻转卡片
 52     public void flipCard() {
 53         // 正面朝上
 54         if (!mIsShowBack) {
 55             inSet.setTarget(mFlCardBack);
 56             outSet.setTarget(mFlCardFront);
 57             mIsShowBack = true;
 58         } else { // 背面朝上
 59             inSet.setTarget(mFlCardFront);
 60             outSet.setTarget(mFlCardBack);
 61             mIsShowBack = false;
 62         }
 63         inSet.start();
 64         outSet.start();
 65     }
 66 
 67     AnimatorListenerAdapter animatorListenerAdapter = new AnimatorListenerAdapter() {
 68         @Override
 69         public void onAnimationStart(Animator animation) {
 70             super.onAnimationStart(animation);
 71             mFlContainer.setClickable(false);//在动画执行过程中,不许允许接收点击事件
 72         }
 73 
 74         @Override
 75         public void onAnimationEnd(Animator animation) {
 76             super.onAnimationEnd(animation);
 77             mFlContainer.setClickable(true);//在动画执行过程中,不许允许接收点击事件
 78         }
 79     };
 80 
 81     private AnimatorSet inSet, outSet;
 82 
 83     private void initAnimatorSet() {
 84         inSet = new AnimatorSet();
 85         ObjectAnimator animator = ObjectAnimator.ofFloat(null, "rotationY", -180f, 0f);
 86         animator.setDuration(500);
 87         animator.setStartDelay(0);
 88         ObjectAnimator animator2 = ObjectAnimator.ofFloat(null, "alpha", 0.0f, 1f);
 89         animator2.setStartDelay(250);
 90         animator2.setDuration(0);
 91         inSet.playTogether(animator, animator2);
 92         inSet.addListener(animatorListenerAdapter);
 93 
 94         outSet = new AnimatorSet();
 95         ObjectAnimator animator_ = ObjectAnimator.ofFloat(null, "rotationY", 0, 180f);
 96         animator_.setDuration(500);
 97         animator_.setStartDelay(0);
 98         ObjectAnimator animator2_ = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
 99         animator2_.setStartDelay(250);
100         animator2_.setDuration(0);
101         outSet.playTogether(animator_, animator2_);
102         outSet.addListener(animatorListenerAdapter);
103     }
104 
105 }

 

2) 用 animator.xml来配置动画特效,然后在java代码中执行动画

 1 package com.example.cardrotation;
 2 
 3 import android.animation.Animator;
 4 import android.animation.AnimatorInflater;
 5 import android.animation.AnimatorListenerAdapter;
 6 import android.animation.AnimatorSet;
 7 import android.support.v7.app.AppCompatActivity;
 8 import android.os.Bundle;
 9 import android.view.View;
10 import android.widget.FrameLayout;
11 
12 /**
13  * 旋转卡片特效
14  * 第2种写法
15  *
16  * 用animator.xml的配置来描述动画特效
17  * 在代码中,执行动画
18  *
19  */
20 public class MainActivity extends AppCompatActivity {
21 
22     private FrameLayout mFlCardBack, mFlCardFront, mFlContainer;
23 
24     @Override
25     protected void onCreate(Bundle savedInstanceState) {
26         super.onCreate(savedInstanceState);
27         setContentView(R.layout.activity_main);
28 
29         mFlCardBack = findViewById(R.id.fl_back);
30         mFlCardFront = findViewById(R.id.fl_front);
31         mFlContainer = findViewById(R.id.main_fl_container);
32         mFlContainer.setOnClickListener(new View.OnClickListener() {
33             @Override
34             public void onClick(View v) {
35                 flipCard();
36             }
37         });
38 
39         initAnimatorSet(); // 设置动画
40         setCameraDistance(); // 设置镜头距离
41     }
42 
43     // 改变视角距离, 贴近屏幕,这个必须设置,因为如果不这么做,沿着Y轴旋转的过程中有可能产生超出屏幕的3D效果。
44     private void setCameraDistance() {
45         int distance = 16000;
46         float scale = getResources().getDisplayMetrics().density * distance;
47         mFlCardFront.setCameraDistance(scale);
48         mFlCardBack.setCameraDistance(scale);
49     }
50 
51     private boolean mIsShowBack = false;
52 
53     // 翻转卡片
54     public void flipCard() {
55         // 正面朝上
56         if (!mIsShowBack) {
57             mRightOutSet.setTarget(mFlCardFront);
58             mLeftInSet.setTarget(mFlCardBack);
59             mIsShowBack = true;
60         } else { // 背面朝上
61             mRightOutSet.setTarget(mFlCardBack);
62             mLeftInSet.setTarget(mFlCardFront);
63             mIsShowBack = false;
64         }
65         mRightOutSet.start();
66         mLeftInSet.start();
67     }
68 
69     private AnimatorSet mRightOutSet, mLeftInSet;
70     AnimatorListenerAdapter animatorListenerAdapter = new AnimatorListenerAdapter() {
71         @Override
72         public void onAnimationStart(Animator animation) {
73             super.onAnimationStart(animation);
74             mFlContainer.setClickable(false);//在动画执行过程中,不许允许接收点击事件
75         }
76 
77         @Override
78         public void onAnimationEnd(Animator animation) {
79             super.onAnimationEnd(animation);
80             mFlContainer.setClickable(true);//在动画执行过程中,不许允许接收点击事件
81         }
82     };
83 
84 
85     private void initAnimatorSet() {
86         mRightOutSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.anim_out);
87         mLeftInSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.anim_in);
88 
89         // 设置点击事件
90         mRightOutSet.addListener(animatorListenerAdapter);
91         mLeftInSet.addListener(animatorListenerAdapter);
92     }
93 }

这里用到了xml配置,所以必须在res中写xml

下面贴出anim_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 这里做个说明- 用XML来配置动画效果,下面这种平行的写法其实是让旋转,和透明动画 同时执行,
    startOffset是执行延时,对应ObjectAnimator的 setStartDelay(long startDelay) 方法 -->

    <!--旋转-->
    <objectAnimator
        android:duration="500"
        android:propertyName="rotationY"
        android:valueFrom="-180"
        android:valueTo="0" />

    <!--出现-->
    <objectAnimator
        android:duration="0"
        android:propertyName="alpha"
        android:startOffset="250"
        android:valueFrom="0.0"
        android:valueTo="1.0" />
    <!-- 所以说这个startOffSet的意思就是,这个动画延迟多久ms以后执行 -->
</set>

和anim_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--旋转-->
    <objectAnimator
        android:duration="500"
        android:propertyName="rotationY"
        android:valueFrom="0"
        android:valueTo="180" />

    <!--消失-->
    <objectAnimator
        android:duration="0"
        android:propertyName="alpha"
        android:startOffset="250"
        android:valueFrom="1.0"
        android:valueTo="0.0" />
</set>

OK,关键代码上面已经给出。

下面是公共部分布局的代码:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_fl_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include layout="@layout/cell_card_back" />

    <include layout="@layout/cell_card_front" />

</FrameLayout>

  

卡片反面cell_card_back.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fl_back"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:text="反面"
        android:textColor="@color/colorAccent"
        android:textSize="30sp" />

</FrameLayout>

卡片正面 cell_card_front.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    android:id="@+id/fl_front">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/darker_gray"
        android:gravity="center"
        android:text="正面"
        android:textColor="@color/colorPrimary"
        android:textSize="30sp" />
</FrameLayout>

 

OK,完事。

所有的动画特效基本都有这两种写法。

具体用什么,看心情吧。 

用纯java,可能api查起来方便一点,毕竟xml写配置,不能alt点进去看属性说明。

用xml的话,可能在代码端就简洁一点,属性,自己想办法上网查好了。

就这样了·····

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

访问者模式Visitor

一 概述 场景:通常来说,用于封装数据所用到的pojo类,其只包含get、set,对应的业务逻辑是在Service上完成的;但如果出现多个pojo类都共用一套逻辑时,则应该考虑将逻辑进行抽象,不同类型...

小明不觉小
17分钟前
5
0
jQuery Ajax错误处理,显示自定义异常消息 - jQuery Ajax error handling, show custom exception messages

问题: Is there some way I can show custom exception messages as an alert in my jQuery AJAX error message? 有没有什么方法可以在我的jQuery AJAX错误消息中显示自定义异常消息作为警报...

法国红酒甜
23分钟前
18
0
告别传统机房:3D 机房数据可视化实现智能化与VR技术的新碰撞

前言 随着各行业对计算机依赖性的日益提高,计算机信息系统的发展使得作为其网络设备、主机服务器、数据存储设备、网络安全设备等核心设备存放地的计算机机房日益显现出它的重要地位,而机房...

xhload3d
昨天
19
0
如何使用.css()应用!important? - How to apply !important using .css()?

问题: I am having trouble applying a style that is !important . 我在应用!important样式时遇到麻烦。 I've tried: 我试过了: $("#elem").css("width", "100px !important"); This doe......

富含淀粉
昨天
5
0
spring源码解析-xml配置文件读取

整个 XML配置文件读取的大致流程如下: 通过继承自AbstractBeanDefinitionReader中的方法,来使用ResourLoader将资源文件路径转换为对应的Resource文件(读取资源文件并将其转为Resource) ...

wc_飞豆
昨天
16
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部