您的位置:首页 > 移动开发 > Android开发

Android 卡片翻转动画效果

2017-11-18 20:48 330 查看

转载请标明出处:http://blog.csdn.net/android_mnbvcxz/article/details/78570594

Android 卡片翻转动画效果

前言

前端时间开发一款应用APP,里面展示的内容需要用到卡片元素,卡片的正面显示主要信息,卡片的背面显示详细信息,单击卡片实现翻转动画的效果。
在这里我给出了两个卡片翻转动画效果的样式,废话不多说,让我们一起看看效果吧:

翻转动画一



翻转动画二



一、卡片翻转动画效果一详解

1.1 界面布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/choose_product_item_ly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@android:color/transparent"
app:cardCornerRadius="@dimen/radius"
app:cardElevation="4dp"
app:cardMaxElevation="4dp"
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="true">

<include layout="@layout/ly_choose_product_item_back" /><!--反面布局-->

<include layout="@layout/ly_choose_product_item_front" /><!--正面布局-->

</android.support.v7.widget.CardView>


:在CardView控件里面include了两个正面和反面两个布局,用于分别显示各自的内容(这里面的代码就不贴了)

1.2 自定义3D旋转动画类(继承Animation)

/**
* 3D旋转动画
*/
public class Rotate3dAnimation extends Animation {
// 开始角度
private final float mFromDegrees;
// 结束角度
private final float mToDegrees;
// 中心点
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
// 是否需要扭曲
private final boolean mReverse;
// 摄像头
private Camera mCamera;

public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX,
float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}

@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}

// 生成Transformation
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
// 生成中间角度
float degrees = fromDegrees
+ ((mToDegrees - fromDegrees) * interpolatedTime);

final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;

final Matrix matrix = t.getMatrix();

camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
// 取得变换后的矩阵
camera.getMatrix(matrix);
camera.restore();

matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}


1.3 设置动画监听

/**
* 动画执行动作监听
*/
private final class DisplayNextView implements Animation.AnimationListener {

public void onAnimationStart(Animation animation) {
}

// 动画结束
public void onAnimationEnd(Animation animation) {

item_ly.post(new Runnable() {
@Override
public void run() {
if (item_front_ly.getVisibility() == View.VISIBLE) {
applyRotation(view, 90, 0, false);
} else {
applyRotation(view, -90, 0, false);
}
}
});

if (item_front_ly.getVisibility() == View.VISIBLE) {
item_front_ly.setVisibility(View.GONE);
item_back_ly.setVisibility(View.VISIBLE);

} else {
item_front_ly.setVisibility(View.VISIBLE);
item_back_ly.setVisibility(View.GONE);

}
}

public void onAnimationRepeat(Animation animation) {
}
}
:这里动画监听的主要功能是判断:如果之前显示的是正面,则在动画结束后隐藏正面,显示反面;反之,隐藏反面,显示正面

1.4 设置旋转动画

/**
* 设置旋转动(画动画效果1)
* @param view
* @param start
* @param end
* @param reverse
*/
private void applyRotation(View view, float start, float end, boolean reverse) {
// 计算中心点
float centerX = view.getWidth() / 2.0f;
float centerY = view.getHeight() / 2.0f;
Rotate3dAnimation rotation = new Rotate3dAnimation(start, end,
centerX, centerY, 300.0f, reverse);
rotation.setDuration(300);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
if (reverse)
rotation.setAnimationListener(new DisplayNextView()); // 设置监听
view.startAnimation(rotation);
}


二、卡片翻转动画效果二详解

2.1 界面布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_ly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:background="@android:color/transparent">

<include layout="@layout/ly_item_back" /><!--反面布局-->

<include layout="@layout/ly_item_front" /><!--正面布局-->

</FrameLayout>


2.2 设置动画

// 设置动画(动画效果1)
private void setAnimators(final View view) {
mRightOutSet = (AnimatorSet) AnimatorInflater.loadAnimator(mContext, R.animator.card_flip_anim_out);
mLeftInSet = (AnimatorSet) AnimatorInflater.loadAnimator(mContext, R.animator.card_filp_anim_in);
// 设置点击事件
mRightOutSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
view.setClickable(false);
}
});
mLeftInSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setClickable(true);
}
});
}

:初始化右出(RightOut)和左入(LeftIn)动画,
使用动画集合AnimatorSet。当右出动画开始时, 点击事件无效, 当左入动画结束时, 点击事件恢复.

2.2.1 右出动画(在动画资源文件夹animator中创建动画文件card_flip_anim_out.xml)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--旋转-->
<objectAnimator
android:duration="3000"<!--总共旋转时间,单位ms-->
android:propertyName="rotationY"
android:valueFrom="0"
android:valueTo="180"/>

<!--消失-->
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:startOffset="1500"<!--背面布局出现时间(也是正面布局消失时间,正好是总共旋转时间的一半),单位ms-->
android:valueFrom="1.0"
android:valueTo="0.0"/>
</set>

:右出动画会旋转180°,
当旋转一半时, 正面卡片消失

2.2.2 左入动画(在动画资源文件夹animator中创建动画文件card_flip_anim_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="3000"
android:propertyName="rotationY"
android:valueFrom="-180"
android:valueTo="0"/>

<!--出现-->
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:startOffset="1500"
android:valueFrom="0.0"
android:valueTo="1.0"/>
</set>
:左入动画背面布局在开始时是隐藏,
逆向旋转, 当旋转一半时, 显示卡片。

2.3 镜头视角

/**
* 改变视角距离, 贴近屏幕(动画效果2)
*/
private void setCameraDistance(View front_ly, View back_ly) {
int distance = 16000;
float scale = mContext.getResources().getDisplayMetrics().density * distance;
front_ly.setCameraDistance(scale);
back_ly.setCameraDistance(scale);
}
:改变视角,
涉及到旋转卡片的Y轴, 即rotationY, 需要修改视角距离。如果不修改, 则会超出屏幕高度, 影响视觉体验.

3.4 旋转控制

/**
* 翻转动画(动画效果1)
*
* @param v
*/
private void flipCard(View v) {

// 正面朝上
if (isShowBack()) {
setShowBack(false);

mRightOutSet.setTarget(item_front_ly);
mLeftInSet.setTarget(item_back_ly);
mRightOutSet.start();
mLeftInSet.start();
} else { // 背面朝上
setShowBack(true);

mRightOutSet.setTarget(item_back_ly);
mLeftInSet.setTarget(item_front_ly);
mRightOutSet.start();
mLeftInSet.start();
}
}


源码我还没有从项目中剥离出来,要是公司项目一起上传的话,感觉会被砍,所以我就不上传了,要是有问题的话可以相互交流交流。

参考: http://blog.csdn.net/easyer2012/article/details/50483930
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: