Android翻转动画(卡片翻转效果)

举报
计蒙不吃鱼 发表于 2025/06/08 18:31:43 2025/06/08
【摘要】 本文介绍了如何实现卡片翻转动画效果,通过Android中的ObjectAnimator结合不同插值器(LinearInterpolator、AccelerateInterpolator、DecelerateInterpolator)完成平滑过渡。示例中以按钮点击触发动画,核心逻辑包括判断视图可见性、设置旋转角度及处理初始Bug(如第一次点击异常)。

前言

最近好友问计蒙翻转动画,恰好在大二那年看Android Api Demo时记了笔记,由此写一篇文章。

需求

屏幕右滑事件触发卡片的翻转效果 ,为了方便,在例子中将右滑事件改成按钮点击事件

老规矩,最后有源码

一、先介绍三个插值器

LinearInterpolator() 其变化速率恒定
AccelerateInterpolator() 其变化开始速率较慢,后面加速
DecelerateInterpolator() 其变化开始速率较快,后面减速

二、实现步骤

1.效果图

2.布局

一个按钮,两个TextView(布局文件在源码部分)

3.逻辑判断(是否隐藏)

        final TextView visibletext;
        final TextView invisibletext;
        //逻辑判断
        if (textview1.getVisibility() == View.GONE) {
            visibletext = textview2;
            invisibletext = textview1;
        } else {
            invisibletext = textview2;
            visibletext = textview1;
        }

4.翻转动画

 //LinearInterpolator()     其变化速率恒定
        ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibletext, "rotationY", 0f, 90f);
        visToInvis.setDuration(500);
        //AccelerateInterpolator()    其变化开始速率较慢,后面加速
        visToInvis.setInterpolator(new AccelerateInterpolator());
        final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibletext, "rotationY",
                -90f, 0f);
        invisToVis.setDuration(500);
        //DecelerateInterpolator()   其变化开始速率较快,后面减速
        invisToVis.setInterpolator(new DecelerateInterpolator());
        visToInvis.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator anim) {
                visibletext.setVisibility(View.GONE);
                invisToVis.start();
                invisibletext.setVisibility(View.VISIBLE);
            }
        });
        visToInvis.start();

5.bug出现

发现实现后,第一次点击出现bug

6.bug解决

在找到控件后,默认设置y方向角度

textview2.setRotationY(-90f);

三、源码

MainActivity.java

public class MainActivity extends Activity {

    private TextView textview1;
    private TextView textview2;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        //bug解决
        textview2.setRotationY(-90f);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                flipAnimation();
            }
        });
    }

    private void initView() {
        textview1 = (TextView) findViewById(R.id.textview1);
        textview2 = (TextView) findViewById(R.id.textview2);
        button = (Button) findViewById(R.id.button);
    }

    private void flipAnimation() {
        final TextView visibletext;
        final TextView invisibletext;
        //逻辑判断
        if (textview1.getVisibility() == View.GONE) {
            visibletext = textview2;
            invisibletext = textview1;
        } else {
            invisibletext = textview2;
            visibletext = textview1;
        }
        //LinearInterpolator()     其变化速率恒定
        ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibletext, "rotationY", 0f, 90f);
        visToInvis.setDuration(500);
        //AccelerateInterpolator()    其变化开始速率较慢,后面加速
        visToInvis.setInterpolator(new AccelerateInterpolator());
        final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibletext, "rotationY",
                -90f, 0f);
        invisToVis.setDuration(500);
        //DecelerateInterpolator()   其变化开始速率较快,后面减速
        invisToVis.setInterpolator(new DecelerateInterpolator());
        visToInvis.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator anim) {
                visibletext.setVisibility(View.GONE);
                invisToVis.start();
                invisibletext.setVisibility(View.VISIBLE);
            }
        });
        visToInvis.start();
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<TextView
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:background="#35B9F4"
    android:id="@+id/textview1"
    android:layout_centerInParent="true"
    />
<TextView
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:background="#03DAC5"
    android:layout_centerInParent="true"
    android:id="@+id/textview2"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:id="@+id/button"
    android:text="点击翻转"/>
</RelativeLayout>

四、总结

最后将button的点击事件改成屏幕监听事件即可。
希望对您有所帮助,欢迎留言。如有问题可联系计蒙。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。