版权说明 : 《Android转场动画和共享元素动画兼容5.0以下版本的实现》于当前CSDN博客和乘月网属同一原创,转载请说明出处,谢谢。

一款APP让人赏心悦目的APP,动画是它并不可少的部分,Android提供很多原生动画方式如帧动画,属性动画等,也提供了一些组件动画套装,如Activity间的过渡跳转动画,还有Fragment,Dialog等展示动画。本文只讲Android转场动画和共享元素动画。

CySharedElementTransition

A compat library of android shared-element transition for lower api.
一个为Android较低版本api提供Android共享元素转场动画的兼容库。

开源库地址:https://github.com/ausboyue/CySharedElementTransition

Activity转场动画

先看效果图

Activity降落过渡动画 ↓↓↓

Android转场动画和共享元素动画兼容5.0以下版本的实现_第1张图片

Activity左滑过渡动画 ↓↓↓

Android转场动画和共享元素动画兼容5.0以下版本的实现_第2张图片

这些动画一定程度上提高了良好的用户交互视觉感受,但是还有更高层次的过渡动画,那就是基于控件(View)级别的过渡动画(共享元素动画的精髓)。

共享元素动画

Google在Android5.0时开始集成了更多更全面更易于开发者定义的的转场动画和共享元素动画。

下面我们看看示例Google Play:

Android转场动画和共享元素动画兼容5.0以下版本的实现_第3张图片

当你点击app logo时,这个logo会通过动画引导出下一个界面,引导过程中逐渐显示界面剩余的所有元素(View),完成非常平滑界面过渡。由于录制和图片压缩的原因,效果图画面比较模糊,画面有白闪,卡顿现象,真实效果大家可以下载体验下。

然而作为挖坑大师的Google从不吝啬在自己的每一个产品上给开发者挖坑–Android5.0以下版本无法使用该类型的动画

Android转场动画和共享元素动画兼容5.0以下版本的实现_第4张图片

这就意味着如果想让自己的APP气质提高一个档次,在应用这些牛逼的动画时需要这样做?

if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {    Toast.makeText(context, "请先升级5.0及以上的系统或换好一点的手机吧!", Toast.LENGTH_SHORT).show();    finish();    return;}

好主意,专治各种不服!可是直到有一天产品小哥突然敲敲地凑到你的耳边对你说:↓↓↓

Android转场动画和共享元素动画兼容5.0以下版本的实现_第5张图片

我…!!! 那个,请转告老板,把工资给我结一下,谢谢。

Android转场动画和共享元素动画兼容5.0以下版本的实现_第6张图片

可不能这么快就认怂,没有官方的支持,我们就走“曲线救国”爬坑之路呗。虽然实现起来有些麻烦,但也没那么可怕,下面正式进入主题。


ActivityA跳转至ActivityB

简述流程

  1. 获取ActivityA元素信息(如View的大小,位置,id)即属性值材料,作为转场动画的初始值
  2. ActivityA通过Intent传递给ActivityB
  3. ActivityB设为全透明(Window和Content Layout以及元素View皆为透明)
  4. ActivityB读取Intent中的初始值信息并为其元素准备转场动画
  5. ActivityB执行共享元素转场动画
start跳转 获取ActivityA的元素信息 构建Intent ActivityB读取Intent转场信息 ActivityB设为全透明 ActivityB准备转场动画 ActivityB执行转场动画

我们以上述google play的转场动画为例,ActivityA上有个app logo即为ImageViewA,ActivityB的即为ImageViewB,logo图片的资源地址为imgUrl。下面用代码示例走流程:

详细代码流程

1. 获取ActivityA的元素信息

private Bundle createMaterials(View view) {    // 位置坐标    int[] location = new int[2];    view.getLocationOnScreen(location);    Bundle b = new Bundle();    int left = location[0];    int top = location[1];        // 宽高大小    int width = view.getWidth();    int height = view.getHeight();        // 传入Bundle    b.putInt("left", left);    b.putInt("top", top);    b.putInt("width", width);    b.putInt("height", height);    return b;}

2. 在ActivityA中构建Intent

// 获取初始值材料Bundle materials=createMaterials(imageViewA);Intent intent = new Intent(activityA, ActivityB.class);intent.putExtra(EXTRA_IMG_URL, imgUrl);// 传入构建好的View属性值材料intent.putExtra(EXTRA_VIEW_ATTRS_MATERIALS , materials);startActivity(intent);// 禁止系统默认动画overridePendingTransition(0, 0);

3. ActivityB设为全透明

  • Window设为透明,在ActivityB主题(style)中设置
<style name="WindowTransparent" parent="AppTheme">    "android:windowIsTranslucent">true    "android:windowBackground">@android:color/transparentstyle>
  • Layout以及元素View设为透明
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical">    <ImageView        android:id="@+id/iv_head"        android:layout_width="100dp"        android:layout_height="100dp"        android:scaleType="centerCrop"        android:visibility="invisible"/>LinearLayout>

4. ActivityB读取Intent转场信息

private void prepareTransition() {    int[] location = new int[2];    imageViewB.getLocationOnScreen(location);        // 移动到ActivityA元素imageViewA同样的位置       deltaX = imageViewALeft - location[0];    deltaY = imageViewATop - location[1];    imageViewB.setTranslationX(deltaX);    imageViewB.setTranslationY(deltaY);        // 缩放到imageViewA同样的大小    scaleX = (float) imageViewAWidth / imageViewB.getWidth();    scaleY = (float) imageViewAHeight / imageViewB.getHeight();    imageViewB.setScaleX(scaleX);    imageViewB.setScaleY(scaleY);}

5. ActivityB执行共享元素转场动画

private void runEnterAnimation() {        imageViewB.setVisibility(View.VISIBLE);            // 加载图片,如Glide        Glide.with(context).load(imgUrl).into(imageViewB);                // 执行动画        imageViewB.animate()                .setDuration(DEFAULT_DURATION)                .setInterpolator(DEFAULT_INTERPOLATOR)                .scaleX(1f)                .scaleY(1f)                .translationX(0)                .translationY(0)                .start();    }

ActivityB回退至ActivityA

流程比较简单,直接上代码喽:

private void runExitAnimation() {    // 执行回退动画    imageViewB.animate()            .setDuration(DEFAULT_DURATION)            .setInterpolator(DEFAULT_INTERPOLATOR)            .scaleX(scaleX)            .scaleY(scaleY)            .translationX(deltaX)            .translationY(deltaY)            .withEndAction(new Runnable() {                @Override                public void run() {                    // 关闭ActivityB                    finish();                    // 禁止系统默认动画                    overridePendingTransition(0, 0);                }            }).start();    }

OK,大体流程如上,Demo效果图如下:


如果想深入地学习,大家可以了解下我的开源库,可供学习,亦可集成到项目中使用。

CySharedElementTransition

A compat library of android shared-element transition for lower api.
一个为Android较低版本api提供Android共享元素转场动画的兼容库。

开源库地址:https://github.com/ausboyue/CySharedElementTransition

ScreenShot

Download from Gradle

Add to your root build.gradle:

allprojects {    repositories {        ...        maven { url 'https://jitpack.io' }    }}

Add the dependency:

dependencies {    implementation 'com.github.ausboyue:CySharedElementTransition:1.0.1'}

Friendly Hints

If you can’t download it, maybe you have used the Google’s repository that you can’t connect to the Google server.Please open the proxy or top the target repository.As follows(如果你无法下载这个库,你可能使用了google的仓库。请开启代理或者置顶目标仓库,如下所示):

allprojects {    repositories {        maven { url 'https://jitpack.io' } // target repository,be top        jcenter()        google() // Google's repository    }}

Download from Maven

Add the JitPack repository to your build file:

<repositories><repository>    <id>jitpack.ioid>    <url>https://jitpack.iourl>repository>repositories>

Add the dependency:

<dependency>    <groupId>com.github.ausboyuegroupId>    <artifactId>CySharedElementTransitionartifactId>    <version>1.0.1version>dependency>

Get Started

1. ActivityA jump to ActivityB,when need use “SharedElementTransition”(ActivityA 跳转到ActivityB,当需要用到“共享元素转场动画”时):

  • ActivityA edit code as below(编辑ActivityA 的代码如下):
CySharedElementTransition.startActivity(intent, activityA, view1, view2, view...);
  • ActivityB edit code as below(编辑ActivityB 的代码如下):
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    ......    CySharedElementTransition.runEnterAnim(activityB);    ......}

2. ActivityB back to ActivityA(ActivityB Ac回到ActivityA):

  • ActivityB edit code like this(编辑ActivityB 的代码,类似代码如下):
@Overridepublic void onBackPressed() {    CySharedElementTransition.runExitAnim(activityB);}

更多相关文章

  1. Android实用视图动画及工具系列之四:多状态CheckBox,可设置大小尺
  2. Android:通过ValueAnimator动画改变控件长宽失效的问题解决
  3. Android中重复执行动画bug
  4. Android Activity间的过渡动画
  5. Android 动画学习笔记
  6. android动画效果2
  7. 弹球效果动画
  8. Android 开关机动画

随机推荐

  1. 15、android 用toast实现简单的进度显示
  2. Android(安卓)PullToRefreshView巴黎埃菲
  3. android,编译过程遇到的错误
  4. Android(安卓)多渠道打包
  5. Android实用代码片段(一)
  6. Android之Spinner解析
  7. android:启动界面设计
  8. Android(安卓)Message里传送的数据
  9. 2013.12.04 (3)——— android SlidingMenu
  10. Android(安卓)最简单的SD卡文件遍历程序