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

Android Study Material Design 十六 动画实践以及拓展

2017-12-19 01:06 686 查看
LZ-Says:路是自己走得,好坏自己都要走下去~只要自己认为是对的~!!!



前言

针对上篇 Android Study 之 属性动画初识 ,我们实现一个小效果,具体如下:



这个图录的恶心的,大伙凑合看。

分析

基于上面的gif图,我们简要分析下,如果要实现上面的骚操作,我们改怎么做?

首先,点击显示按钮,背景首先执行翻转动画,接着开启透明动画,最后开启缩放动画

那么,基于以上分析我们开始着手实践。

开搞 谁知道 有没有坑 ^_^

首先搭建我们的布局,很是easy,相对布局中承载俩个ImageView以及Button,如下:

<?xml version="1.0" encoding="utf-8"?>
<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.hlq.animalsafari.MainActivity">

<android.support.v7.widget.LinearLayoutCompat
android:id="@+id/ll_first"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/icon_2"
android:orientation="vertical">

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="getStartFirstAnimation"
android:text="显示" />

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="getOut"
android:text="跳转下一页" />

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

<ImageView
android:id="@+id/iv_second"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:clickable="true"
android:onClick="getStartSecondAnimation"
android:scaleType="fitEnd"
android:src="@drawable/icon_1"
android:visibility="gone" />

</RelativeLayout>


然后就是我们刚才分析的动画实现,首先必须要明确一点:

动画,同步执行!!!


再次进行明确流程:

首先进行翻转,而翻转的角度是以X轴的角度进行翻转,同时进行透明度的变换,同时进行X,Y轴缩放,最后我们需要将翻转后再次回归原来,也就是翻转到原来的正常角度

// 翻转
ObjectAnimator rotationX = ObjectAnimator.ofFloat(mFirstView, "rotationX", 0f, 25f);
rotationX.setDuration(300);
// 透明
ObjectAnimator alpha = ObjectAnimator.ofFloat(mFirstView, "alpha", 1f, 0.5f);
alpha.setDuration(200);
// 缩放
ObjectAnimator scaleX = ObjectAnimator.ofFloat(mFirstView, "scaleX", 1f, 0.8f);
scaleX.setDuration(300);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(mFirstView, "scaleY", 1f, 0.8f);
scaleY.setDuration(300);

ObjectAnimator resumeRotationX = ObjectAnimator.ofFloat(mFirstView, "rotationX", 25f, 0f);
resumeRotationX.setDuration(200);
// 延迟执行
resumeRotationX.setStartDelay(200);

AnimatorSet set = new AnimatorSet();
set.playTogether(rotationX, alpha, scaleX, scaleY, resumeRotationX);
set.start();


我们一起来看看效果,看看是否达到预期:



这里为什么会出现了上下空白呢?按照原有的效果,应该顶上去才对,那么是哪儿引发的问题呢?

回顾上面,是由于我们缩放导致据屏幕上方约有百分之10的距离,为什么这么说呢?

是因为我们刚才X,Y各自缩放当前百分之80,也就是上下空白各占百分之十。

那么到这里,大家或许心中有了写解决之道。

我们设置一个Y轴平移不就好了么?



So,修改后代码如下:

// 由于缩放造成 离顶部有一段距离 需要平移上去
ObjectAnimator translationY = ObjectAnimator.ofFloat(mFirstView, "translationY", 0f, -0.1f * mFirstView.getHeight());
translationY.setDuration(200);


别忘记将此平移效果添加同步执行中哦~

set.playTogether(rotationX, alpha, scaleX, scaleY, resumeRotationX, translationY);


再次运行查看效果:



现在的效果是不是完成了小一半?

而接下来,我们只需要在点击的时候,将Image 2 显示并平移上来即可。

// 第二个view执行平移动画 往上
ObjectAnimator secondTranslationY = ObjectAnimator.ofFloat(mSecondView, "translationY", mSecondView.getHeight(), 0f);
secondTranslationY.setDuration(200);
secondTranslationY.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mSecondView.setVisibility(View.VISIBLE);
}
});


同时,别忘记添加同步执行:

set.playTogether(rotationX, alpha, scaleX, scaleY, resumeRotationX, translationY, secondTranslationY);


再次运行效果如下:



那么,如何实现点击image 2的时候,image 1呈现呢?

首先我们需要分析下此时动画的执行,我们是不是只需要将image 1过渡到image 2的动画部分反转即可?

代码稍作修改,如下:

private void getAnimationStart() {
// 翻转
ObjectAnimator rotationX = ObjectAnimator.ofFloat(mFirstView, "rotationX", 0f, 25f);
rotationX.setDuration(300);
// 透明
ObjectAnimator alpha = ObjectAnimator.ofFloat(mFirstView, "alpha", 0.5f, 1f);
alpha.setDuration(200);
// 缩放
ObjectAnimator scaleX = ObjectAnimator.ofFloat(mFirstView, "scaleX", 0.8f, 1f);
scaleX.setDuration(300);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(mFirstView, "scaleY", 0.8f, 1f);
scaleY.setDuration(300);

//        rotationX.addUpdateListener();
ObjectAnimator resumeRotationX = ObjectAnimator.ofFloat(mFirstView, "rotationX", 25f, 0f);
resumeRotationX.setDuration(200);
// 延迟执行
resumeRotationX.setStartDelay(200);

// 由于缩放造成 离顶部有一段距离 需要平移上去
ObjectAnimator translationY = ObjectAnimator.ofFloat(mFirstView, "translationY", -0.1f * mSecondView.getHeight(), 0f);
translationY.setDuration(200);

// 第二个view执行平移动画 往上
ObjectAnimator secondTranslationY = ObjectAnimator.ofFloat(mSecondView, "translationY", mSecondView.getHeight(), 0f);
secondTranslationY.setDuration(200);
secondTranslationY.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mSecondView.setVisibility(View.GONE);
}
});

AnimatorSet set = new AnimatorSet();
set.playTogether(rotationX, alpha, scaleX, scaleY, resumeRotationX, translationY, secondTranslationY);
set.start();
}


这样,就实现了我们文章开头显示的效果。

实现的过程很是easy,主要就是通过对动画的组合实现,还有就是实现过程还是需要大家稍微思考下。

而下面,则为大家进行一点拓展。

拓展 Material Design 动画

Material Design,也就是Android 5.0 推出,确实有着nice的效果,也确确实实颠覆了以往Android的印象。

nice的效果中,不乏包含一些好看的效果,比如水波纹效果或者揭露效果。

那么如上这俩种,具体我们又该如何玩转呢?

首先LZ附上最后的效果图:



由于比较easy,这里LZ主要以代码为主:

水波纹,Android 5.0 自带特效,当然你可以引用系统定义好的,直接当作BackGround使用。

But,这里需要注意,使用系统之后,显示效果就是大白,如上图,一个为有边界一个无边界,随便浪。

<Button
android:layout_width="match_parent"
android:layout_height="80dp" />

<Button
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="?attr/selectableItemBackground" />

<Button
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="?attr/selectableItemBackgroundBorderless" />


当然,你可以不使用background,而是直接在style进行配置,如下:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorControlHighlight">@color/colorPrimaryDark</item>
<item name="colorButtonNormal">@color/material_blue_grey_800</item>
</style>


需要注意的是,这个style位于21包下,针对5.0作的兼容。

而关于gif图中关于揭露效果,更是nice+easy~

我们只需要使用提供好的API(ViewAnimationUtils)即可实现,分分钟,首先简单说明api使用如下:

ViewAnimationUtils.createCircularReveal(
view, //作用在哪个View上面
centerX, centerY, //扩散的中心点
startRadius, //开始扩散初始半径
endRadius)//扩散结束半径


其次附上源码:

public void getSelectable(View view) {
Animator circularReveal = ViewAnimationUtils.createCircularReveal(view,
view.getWidth() / 2, view.getHeight() / 2,
0, view.getWidth());
circularReveal.setDuration(1500);
circularReveal.setInterpolator(new AccelerateInterpolator());
circularReveal.start();
}

public void getSelectable1(View view) {
Animator circularReveal = ViewAnimationUtils.createCircularReveal(view,
0, 0,
0, (float) Math.hypot(view.getWidth(), view.getHeight()));
circularReveal.setDuration(1500);
circularReveal.setInterpolator(new AccelerateInterpolator());
circularReveal.start();
}


GitHub查看地址

https://github.com/HLQ-Struggle/AnimalSafari

结束

困了,正好搞完~

祝各位老帖大吉大利,晚上吃鸡~

睡觉去~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息