一个比较有趣的 Android 动画效果
先来看一下效果
分析实现原理:
这里主要知识点是对动画的使用,原理页很简单,在一个 Activity 中布局两个 Fragment,不用 fragment 也行,但是在同一个 xml 中代码量就会比较庞大;初始化的时候让第二个 Fagment 移动到底部隐藏起来,就是刚启动应用时的界面,点击开始之后,执行相应的动画,第一个 Fragment 的 X 和 Y都同时缩小,并且一开始让 X旋转25度,等一定时间,让 X旋转的角度复原,此过程就是 Fragment 的向后移动的动画过程,同时有一个黑色的背景设置它的透明度,从全透到0.5f;第二个Fragment动画就非常简单,单纯的向下和向上移动。
这里就贴一部分代码出来,有兴趣了解的可以直接下载源码下来研究。
贴代码过程:
向后移动动画
mHoverView.setClickable(true);
/*设置背景透明度动画*/
ObjectAnimator animator = ObjectAnimator.ofFloat(mHoverView, "alpha", 0, 0.5f);
/*放小X 的动画*/
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(mOriginalView, "scaleX", 1.0f, .8f);
/*放小Y 的 动画*/
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(mOriginalView, "scaleY", 1.0f, .8f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animator, scaleXAnim, scaleYAnim);
animatorSet.setDuration(350);
animatorSet.start();
/*先让X 旋转20度的动画*/
ObjectAnimator transX = ObjectAnimator.ofFloat(mOriginalView,"RotationX",20.0f);
transX.setDuration(150);
transX.start();
/*等一定时间让X 旋转角度复位*/
ObjectAnimator resumeX = ObjectAnimator.ofFloat(mOriginalView,"RotationX",0.0f);
resumeX.setDuration(200);
resumeX.setStartDelay(150);
resumeX.start();
知道了后退的动画,反过来的动画就很好理解了
mHoverView.setClickable(false);
ObjectAnimator animator = ObjectAnimator.ofFloat(mHoverView, "alpha", 0.5f, 0);
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(mOriginalView, "scaleX", .8f, 1.0f);
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(mOriginalView, "scaleY", .8f, 1.0f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animator, scaleXAnim, scaleYAnim);
animatorSet.setDuration(350);
animatorSet.start();
ObjectAnimator transX = ObjectAnimator.ofFloat(mOriginalView,"RotationX",20.0f);
transX.setDuration(150);
transX.start();
ObjectAnimator resumeX = ObjectAnimator.ofFloat(mOriginalView,"RotationX",0.0f);
resumeX.setDuration(200);
resumeX.setStartDelay(150);
resumeX.start();
以下是第二个 Fragment 上下移动的动画
/**
* Created by moon.zhong on 2015/4/12.
*/
public class AnimationCompat implements Runnable {
private Scroller mScroller;
private View mAnimationView;
private int mViewHeight;
private final int DURATION = 350;
public AnimationCompat(Context context, View view) {
mScroller = new Scroller(context, new LinearInterpolator());
mAnimationView = view;
mViewHeight = mAnimationView.getMeasuredHeight();
if (mViewHeight == 0) {
mAnimationView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mAnimationView.getViewTreeObserver().removeOnPreDrawListener(this);
mViewHeight = mAnimationView.getMeasuredHeight();
return false;
}
});
}
}
public void startHideAnimation(boolean scrollUp) {
int dy = (int) ViewCompat.getTranslationY(mAnimationView) + mViewHeight;
if (!scrollUp) {
dy = (int) ViewCompat.getTranslationY(mAnimationView) - mViewHeight;
}
int duration = (int) Math.abs(DURATION * ViewCompat.getTranslationY(mAnimationView) * 1.0f / mViewHeight);
duration = duration == 0 ? DURATION : duration;
mScroller.startScroll(0, (int) ViewCompat.getTranslationY(mAnimationView), 0, -dy, duration);
ViewCompat.postOnAnimation(mAnimationView, this);
}
public void startShawAnimation() {
int dy = (int) ViewCompat.getTranslationY(mAnimationView);
int duration = (int) Math.abs(DURATION);
mScroller.startScroll(0, dy, 0, -dy, duration);
ViewCompat.postOnAnimation(mAnimationView, this);
}
public void abortAnimation() {
mScroller.abortAnimation();
}
@Override
public void run() {
if (mScroller.computeScrollOffset()) {
ViewCompat.postOnAnimation(mAnimationView, this);
ViewCompat.setTranslationY(mAnimationView, mScroller.getCurrY());
}
}
}
MainActivity的 xml 页贴出来,因为涉及到 fragment 的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:id="@+id/id_anim_content">
<fragment
class="com.test.gyzhong.funanimator.OriginalFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/id_original_fragment"
/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/id_hover_view"
android:background="@android:color/black"
android:alpha="0"/>
<RelativeLayout
android:id="@+id/id_bottom_view"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="@android:color/white"
android:layout_alignParentBottom="true"
android:layout_marginRight="50dp"
android:layout_marginLeft="50dp">
<fragment class="com.test.gyzhong.funanimator.AnimFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/id_fragment_instruct"
/>
</RelativeLayout>
</RelativeLayout>
这里如果把两个 Fragment 的布局全部放到这一个布局文件中,代码将会非常难看,全部集中在一个文件中!
总结:
没有总结,就是要熟运用属性动画!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。