效果展示
实现思路
首先是布局,这里只关注动画本身,所以布局文件使用的是两个控件加两张图片
activity_main.xml
文件如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ricky.animation.safari.MainActivity" >
<LinearLayout
android:id="@+id/first"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/icon2"
android:orientation="vertical"
>
<Button
android:id="@+id/bt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="显示"
android:background="#f00"
android:onClick="startFirstAnim"/>
</LinearLayout>
<ImageView
android:orientation="vertical"
android:id="@+id/second"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/icon1"
android:scaleType="fitXY"
android:layout_alignParentBottom="true"
android:onClick="startSecondAnim"
android:visibility="invisible"
android:clickable="true"
/>
</RelativeLayout>
- 这里有个小技巧,我们的ImageView是对齐父控件的底部,而且设置为不可见,方便我们后面实现滑出动画。
我们可以分解动画,实际上第一个界面隐藏,第二个界面滑入和第一个界面弹出,第二个界面再滑出是两组相对的动画来完成的,我们只需要关注其中一个,另一个自然也就容易实现了。
startFirstAnim
点击事件的代码
//缩放效果
ObjectAnimator firstScaleXAnim = ObjectAnimator.ofFloat(first, "scaleX", 1.0f, 0.8f);
firstScaleXAnim.setDuration(300);
ObjectAnimator firstScaleYAnim = ObjectAnimator.ofFloat(first, "scaleY", 1.0f, 0.8f);
firstScaleYAnim.setDuration(300);
//隐藏效果
ObjectAnimator firstAlphaAnim = ObjectAnimator.ofFloat(first, "alpha", 1.0f, 0.5f);
firstAlphaAnim.setDuration(300);
//旋转效果
ObjectAnimator firstRotationXAnim = ObjectAnimator.ofFloat(first, "rotationX", 0f, 20f);
firstRotationXAnim.setDuration(200);
//恢复旋转效果
ObjectAnimator firstResumeRotationXAnim = ObjectAnimator.ofFloat(first, "rotationX", 20f, 0f);
firstResumeRotationXAnim.setDuration(200);
firstResumeRotationXAnim.setStartDelay(200);
//向上平移动画
ObjectAnimator firstTranslationYAnim = ObjectAnimator.ofFloat(first, "translationY", 0, -0.1f * first.getHeight());
firstTranslationYAnim.setDuration(300);
//向上平移动画
ObjectAnimator secondTranslationYAnim = ObjectAnimator.ofFloat(second, "translationY", second.getHeight(), 0f);
secondTranslationYAnim.setDuration(300);
secondTranslationYAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
second.setVisibility(View.VISIBLE);
}
});
AnimatorSet set = new AnimatorSet();
set.playTogether(firstScaleXAnim, firstScaleYAnim, firstAlphaAnim, firstRotationXAnim, firstResumeRotationXAnim, firstTranslationYAnim, secondTranslationYAnim);
set.start();
所有
first
开头命名的动画都是控制第一个布局控件的动画,将first动画分解开:
- 缩小控件
- 透明度降低
- 沿着X方向往里旋转
- 往里旋转结束后,再旋转回来
- 向上平移
PS:缩小第一个控件后最上面会留白,所以需要向上平移来填充最上部
second
控件动画就是从最下部画出来,可以从代码secondTranslationYAnim.addListener
,我们监听了该动画的onAnimationStart
事件,这样可以在动画开始时设置第二控件的可见性
这样就实现了第一部分的动画,第二部分动画也就是第一个动画的反向,所以这里就不赘述了。