Android实现卡片翻转动画
程序员文章站
2023-12-22 16:07:58
最近项目上用到了卡片的翻转效果,大致研究了下,也参考了网上的一些demo,简单实现如下:
activity_main.xml
最近项目上用到了卡片的翻转效果,大致研究了下,也参考了网上的一些demo,简单实现如下:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <framelayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/card_main_container" android:layout_height="match_parent" android:layout_width="match_parent"> <include layout="@layout/activity_card_back"/> <include layout="@layout/activity_card_front"/> </framelayout>
可以看出,用到了两个布局
activity_card_back.xml
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/card_back_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginleft="@dimen/activity_horizontal_margin" android:layout_margintop="@dimen/activity_vertical_margin" android:layout_marginright="@dimen/activity_horizontal_margin" android:layout_marginbottom="@dimen/activity_vertical_margin" android:background="@drawable/shape_card_back_bg" android:orientation="vertical"> <textview android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="背面" android:textsize="30sp"/> </linearlayout>
activity_card_front.xml
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/card_font_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginleft="@dimen/activity_horizontal_margin" android:layout_margintop="@dimen/activity_vertical_margin" android:layout_marginright="@dimen/activity_horizontal_margin" android:layout_marginbottom="@dimen/activity_vertical_margin" android:background="@drawable/shape_card_front_bg" android:orientation="vertical"> <textview android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="正面" android:textsize="30sp"/> </linearlayout>
附上自定义的图片:
shape_card_back_bg.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="30dp"/> <solid android:color="@android:color/holo_red_light"/> </shape>
shape_card_front_bg.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="30dp"/> <solid android:color="@android:color/darker_gray"/> </shape>
主要的逻辑如下:
package com.jackie.flipanimationdemo; import android.animation.animator; import android.animation.animatorinflater; import android.animation.animatorlisteneradapter; import android.animation.animatorset; import android.os.bundle; import android.support.v7.app.appcompatactivity; import android.view.view; import android.widget.framelayout; import android.widget.linearlayout; public class mainactivity extends appcompatactivity implements view.onclicklistener { private framelayout mcardmaincontainer; private linearlayout mcardfontcontainer, mcardbackcontainer; private animatorset mrightoutanimatorset, mleftinanimatorset; private boolean misshowback = false; //是否显示背面 @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initview(); initevent(); } private void initview() { mcardmaincontainer = (framelayout) findviewbyid(r.id.card_main_container); mcardfontcontainer = (linearlayout) findviewbyid(r.id.card_font_container); mcardbackcontainer = (linearlayout) findviewbyid(r.id.card_back_container); setanimators(); // 设置动画 setcameradistance(); // 设置镜头距离 } private void initevent() { mcardmaincontainer.setonclicklistener(this); } private void setanimators() { mrightoutanimatorset = (animatorset) animatorinflater.loadanimator(this, r.animator.anim_right_out); mleftinanimatorset = (animatorset) animatorinflater.loadanimator(this, r.animator.anim_left_in); // 设置点击事件 mrightoutanimatorset.addlistener(new animatorlisteneradapter() { @override public void onanimationstart(animator animation) { super.onanimationstart(animation); mcardmaincontainer.setclickable(false); } }); mleftinanimatorset.addlistener(new animatorlisteneradapter() { @override public void onanimationend(animator animation) { super.onanimationend(animation); mcardmaincontainer.setclickable(true); } }); } private void setcameradistance() { int distance = 16000; float scale = getresources().getdisplaymetrics().density * distance; mcardfontcontainer.setcameradistance(scale); mcardbackcontainer.setcameradistance(scale); } private void flipcard() { if (!misshowback) { // 正面朝上 mrightoutanimatorset.settarget(mcardfontcontainer); mleftinanimatorset.settarget(mcardbackcontainer); mrightoutanimatorset.start(); mleftinanimatorset.start(); misshowback = true; } else { // 背面朝上 mrightoutanimatorset.settarget(mcardbackcontainer); mleftinanimatorset.settarget(mcardfontcontainer); mrightoutanimatorset.start(); mleftinanimatorset.start(); misshowback = false; } } @override public void onclick(view v) { switch (v.getid()) { case r.id.card_main_container: flipcard(); break; } } }
用到一些动画的资源:
anim_left_in.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <!--消失--> <objectanimator android:duration="0" android:propertyname="alpha" android:valuefrom="1.0" android:valueto="0.0"/> <!--旋转--> <objectanimator android:duration="@integer/anim_length" android:propertyname="rotationy" android:valuefrom="-180" android:valueto="0"/> <!--出现--> <objectanimator android:duration="0" android:propertyname="alpha" android:startoffset="@integer/anim_half_length" android:valuefrom="0.0" android:valueto="1.0"/> </set>
anim_right_out.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <!--旋转--> <objectanimator android:duration="@integer/anim_length" android:propertyname="rotationy" android:valuefrom="0" android:valueto="180"/> <!--消失--> <objectanimator android:duration="0" android:propertyname="alpha" android:startoffset="@integer/anim_half_length" android:valuefrom="1.0" android:valueto="0.0"/> </set>
用到了属性动画,为了兼容性,别忘了如下配置:
效果图如下:
效果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。