android共享元素动画兼容低版本
文章目录
- 共享元素动画
- 5.0以上系统方案
- 详细代码流程
- 5.0以下兼容方案
- 简述流程
- 详细代码流程
上篇: activity转场动画
一款APP让人赏心悦目的APP,动画是它并不可少的部分,Android提供很多原生动画方式如帧动画,属性动画等,也提供了一些组件动画套装,如Activity间的过渡跳转动画,还有Fragment,Dialog等展示动画。本文只讲Android转场动画和共享元素动画。
共享元素动画
Google在Android5.0时开始集成了更多更全面更易于开发者定义的的转场动画和共享元素动画。
下面我们看看示例Google Play:
当你点击app logo时,这个logo会通过动画引导出下一个界面,引导过程中逐渐显示界面剩余的所有元素(View),完成非常平滑界面过渡。由于录制和图片压缩的原因,效果图画面比较模糊,画面有白闪,卡顿现象,真实效果大家可以下载体验下。
5.0以上系统方案
Transition 框架是 Android 4.4 KitKat 中加入的,但在 5.0 才开始被人应用起来,
而且这一部分也涉及了 22.0 的 API,虽然有对应的 support.v4 包,但也还是有点问题。
所以这一部分可以说是 5.0 以上适用的方法。
详细代码流程
1.设置 Activity 引用的 theme
设置 windowContentTransitions 为 true,即开启窗口内容过渡
<style name="AppTheme.custom"><item name="colorControlHighlight">@color/ControlHighlight</item><item name="android:windowIsTranslucent">true</item><item name="android:windowContentTransitions">true</item>
</style>
这里遇到一点小问题,即上述 Activity 引用的 style 中不仅设置了 android:windowContentTransitions,也设置了 android:windowIsTranslucent : 让 Activity 的背景为透明,在我测试的时候发现使用共享元素的时候出现了返回时闪屏的现象,解决方法是设置 Activity 背景颜色为透明。
在 onCreate 中:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);getActivity().getWindow().setBackgroundDrawableResource(R.color.transparent);
}
或者在上述的 style 中的 theme 添加:
<item name="android:windowBackground">@android:color/transparent</item>
2.设置共享元素
其实实现这样的效果就是把第一个界面的 ImageView 移动、放大到第二个界面的 ImageView 的位置,借助 API 实现效果可以省去自己写动画的逻辑,但就需要让系统关联两个 View。
而关联两个 View 通过设置 android:transitionName 属性。
首先在第一个界面的 activity_main.xml:
<LinearLayout><ImageViewandroid:id="@+id/img"android:transitionName="testImg"android:scaleType="centerCrop"android:layout_width="match_parent"android:layout_height="160dp" />...
</LinearLayout>
在打开的 Activity 的 xml 中
<LinearLayout><ImageViewandroid:id="@+id/item_img"android:transitionName="testImg"android:scaleType="centerCrop"android:layout_width="match_parent"android:layout_height="380dp" />...
</LinearLayout>
对应的 ImageView 中的android:transitionName属性值必须相同,而对两个控件的大小、id 等属性并无要求。
3.启动设置
第一个 Activity 中,使用共享元素启动新界面方法
MainActivity:
Intent intent = new Intent(getActivity(),SecondActivity.class);
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), mImgView,"testImg");
startActivity(intent,options.toBundle());
在 makeSceneTransitionAnimation 传入的参数中,mImgView 是第一个界面中 ImageView 的实例,第三个参数对应 xml 中的 android:transitionName 的值。
在被打开的 Activity 中
首先加载图片还是要自己写的,其余的需要注意:
返回不再调用finishActivity() 而是 supportFinishAfterTransition()。
@Override
public void onBackPressed() {supportFinishAfterTransition();
}
因为打开新的 Activity 的时候,可能要去加载新的图片,这时候我们需要延迟过渡动画的开始,直到图片加载完成之后再开始动画。否则会出现各种 bug。
所以要在第二个 Activity 中的 onCreate() 中阻止动画的执行:
@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 延迟共享动画的执行postponeEnterTransition();
}
然后在图片加载完成后开始动画:
Glide.with(this).load(data.getImage()).priority(Priority.HIGH).diskCacheStrategy(DiskCacheStrategy.ALL).into(new GlideDrawableImageViewTarget(mImageView){@Overridepublic void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {super.onResourceReady(resource, animation);//图片加载完成的回调中,启动过渡动画supportStartPostponedEnterTransition();}});
当然,启动动画不一定要等待图片加载完成再进行,因为还存在着图片加载失败、加载时间过长等问题,这里只是提出一种方法,实际还是自己看情况决定。
以上只是简单的实现了一种效果,关于 Transition 的使用、共享元素在
Fragment 中的使用、多个共享元素的使用等,在这里暂时不打算细讲。
5.0以下兼容方案
然而作为挖坑大师的Google从不吝啬在自己的每一个产品上给开发者挖坑–Android5.0以下版本无法使用该类型的动画。
5.0以下手动撸代码实现效果,当然5.0以上版本也同样适用。
简述流程
ActivityA跳转至ActivityB
获取ActivityA元素信息(如View的大小,位置,id)即属性值材料,作为转场动画的初始值
ActivityA通过Intent传递给ActivityB
ActivityB设为全透明(Window和Content Layout以及元素View皆为透明)
ActivityB读取Intent中的初始值信息并为其元素准备转场动画
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();// 传入Bundleb.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)中设置
Layout以及元素View设为透明
<?xml version="1.0" encoding="utf-8"?>
<ImageViewandroid: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);// 加载图片,如GlideGlide.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() {@Overridepublic void run() {// 关闭ActivityBfinish();// 禁止系统默认动画overridePendingTransition(0, 0);}}).start();}
OK,大体流程如上,Demo效果图如下:
参考
https://blog.csdn.net/ausboyue/article/details/80035452
https://www.jianshu.com/p/ea51eefa0b5c
android共享元素动画兼容低版本相关推荐
- android共享元素动画_Android共享元素过渡动画
android共享元素动画 In this tutorial we'll implement a different kind of animation transition namely Share ...
- android 沉浸式状态栏 兼容低版本,详解Android沉浸式实现兼容解决办法
自android5.0开始,沉浸式状态栏似乎成为一种潮流,应用里缺少沉浸式总感觉少些什么.于是乎,我开始到处找如何兼容低版本的沉浸式,由于Android平台跨度问题,总遇到一些不如人意的问题.终于,皇 ...
- Android 共享元素动画
Andriod 5.0及之后,开始支持共享元素动画,该动画主要用于两个activity之间,两个Activity可以共享某些控件,Activity A跳转到Activity B的时候,A的某个控件能自 ...
- android 沉浸式状态栏 兼容低版本,Android 沉浸式状态栏适配方案
首先说下什么是沉浸式状态栏:这是android4.4以后开始支持的一种效果,状态栏不再是一个黑条,而是置为透明或者半透明,然后页面延伸到状态栏下面,这样状态栏区域也可以成为app页面显示区域的一部分, ...
- Android 虚拟按键隐藏或显示之后共享元素动画异常解决方案
背景 本篇算是共享元素的第三篇文章.主要还是因为第一篇才会衍生出来了第二篇和第三篇文章,后两篇均属于bug的分析和解决. 1.Android 仿微信朋友圈图片拖拽返回 2.Android 共享元素动画 ...
- android 在使用ViewAnimationUtils.createCircularReveal()无法兼容低版本的情况下,另行实现圆形scale动画...
ViewAnimationUtils.createCircularReveal()的简介: ViewAnimationUtils.createCircularReveal()是安卓5.0才引入的,快速 ...
- android 延时播放动画,HollyTransition: 让APP丝滑般流畅:深入解读Android过渡动画Transition. 共享元素动画、场景动画、过场动画、延时动画...
HollyTransition 零.导读 深入解读Android过渡动画Transition: 页面切换动画(过场动画) 共享元素动画 延时动画 场景动画 一.Transition前世今生 为了支持各 ...
- Android开发之解决NestedScrollView滑动监听兼容低版本的方法
NestedScrollView的滑动监听目前仅限api23及以上,为了兼容低版本如下自定义方法 可以自定义NestedScrollView即可如下: package cn.net.gfan.worl ...
- 3dmax高版本转低版本插件_Fundebug前端JavaScript插件更新至1.8.0,兼容低版本的Android浏览器...
兼容低版本Android浏览器,请大家及时更新. Fundebug前端BUG监控服务 Fundebug是专业的程序BUG监控平台,我们JavaScript插件可以提供全方位的BUG监控,可以帮助开发者 ...
最新文章
- 在Eclipse中使用Maven 2.x指南
- Maven使用详解视频课程——笔记(一)
- 一篇文章带你快速理解JVM运行时数据区 、程序计数器详解 (手画详图)值得收藏!!!
- 动态服务器值 回放报错 没有关联到_性能测试每天两个知识点-web性能脚本回放不成功的解决方法...
- python取出字符串中的偶数_从给定字符串中删除偶数个连续的重复字符
- Struts2.0第三章(文件上传、ajax开发、json、Fastjson、Jackson、注解开发)
- kaggle图像比赛中的submission文件格式解析
- JDK 9中已弃用Java的Observer和Observable
- WildFly 9 –别希望您的控制台像这样!
- android 通知垃圾回收,Android中垃圾回收日志信息
- vc运行库合集 官方正式版 v2019.07.20
- Windows 10 RTM 官方正式版
- 【杂谈】网络修复杂谈
- 解决el-input输入框使用oninput或onkeyup后,v-model双向绑定失效问题
- qlv是什么格式的视频,怎么把qlv格式转换成mp4
- Day 9 淘宝静态页面练习 reset.css样式重置 头部信息结构及样式 自定义图标的样式
- 如何管理时间:重要紧急四象限的思考
- 火影忍者服务器维护时间,1月4日停机更新公告
- 国税局发票查验API接口文档说明
- python汽车_Python 小车代码