用开源项目ActivityOptionsICS让ActivityOptions的动画实现兼容
我之前写过一篇文章是讲解ActivityOption的api方法的(http://www.cnblogs.com/tianzhijiexian/p/4087917.html),当时吐槽各种动画不兼容,完全无视我们4.x或者2.x用户嘛,好在有开源库来帮助我们实现动画。
开源项目地址:https://github.com/tianzhijiexian/ActivityOptionsICS
零、修改style
用这些动画之前,需要对应用的style进行修改,添加一个属性
<item name="android:windowIsTranslucent">true</item>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- 允许使用transitions -->
<item name="android:windowIsTranslucent">true</item>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
一、ActivityOptionsCompatICS
提供了和ActivityOptions、ActivityCompat基本一致的方法来实现相同的动画效果,总共有如下方法。
【注意】这个类必须在view都显示完成后才能使用,可以在点击事件中中或者是用post一个runnable来用。
(1)public static ActivityOptionsCompatICS makeCustomAnimation(Context context,
int enterResId, int exitResId)
参数:
enterId:进入动画的资源ID
exitId:退出动画的资源ID
设置自定义的Activity动画,出入的是动画资源的id。
这个方法和overridePendingTransition(R.anim.slide_bottom_in, android.R.anim.fade_out);十分类似,传入一个进入的动画和一个退出的动画即可
public void customAnim() {
ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeCustomAnimation(this,
R.anim.slide_right_in, R.anim.slide_bottom_out);
ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
}
(2)public static ActivityOptionsCompatICS makeScaleUpAnimation(View source, int startX,
int startY, int width, int height)
参数:
source:一个view对象,用户确定新activity启动的初始坐标
startX:新activity出现的初始X坐标,这个坐标是相对于source的左上角X坐标
startY:新activity出现的初始Y坐标,这个坐标相对于source的左上角Y坐标
width:新activity初始的宽度
height:新activity初始的高度
通过看源码可以很容易理解这些参数的意义
int[] pts = new int[2];//ps = position,目的得到当前view相对于屏幕的坐标
source.getLocationOnScreen(pts);
// 设置起始坐标和起始宽高
opts.mStartX = pts[0] + startX;
opts.mStartY = pts[1] + startY;
opts.mWidth = width;
opts.mHeight = height;
实现的效果是:新的Activity从某个位置以某个大小出现,然后慢慢拉伸渐变到整个屏幕
public void scaleUpAnim(View view) {
ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeScaleUpAnimation(view,
0, 0, //拉伸开始的坐标
view.getMeasuredWidth(), view.getMeasuredHeight());//初始的宽高
ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
}
(3)public static ActivityOptionsCompatICS makeThumbnailScaleUpAnimation(View source,
Bitmap thumbnail, int startX, int startY)
参数:
source:一个view对象,用来确定起始坐标
thumbnail:一个bitmap对象,新的activity将通过这个bitmap渐变拉伸出现,新的activity初始大小就是这个bitmap的大小
startX:新activity初始的X坐标,相对于source左上角的X来说的
startY:新的activity初始的Y坐标,相对于source左上角Y坐标来说的
效果是:一个bitmap慢慢从某个位置拉伸渐变新的activity
public void thumbNailScaleAnim(ImageView view) {
view.setDrawingCacheEnabled(true);
Bitmap bitmap = view.getDrawingCache();
ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeThumbnailScaleUpAnimation(
view, bitmap, 0, 0);
// Request the activity be started, using the custom animation options.
ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
//view.setDrawingCacheEnabled(false);
}
(4)public static ActivityOptionsCompatICS makeSceneTransitionAnimation(Activity activity,
final View sharedElement,int sharedElementId)
参数:
activity:当前activity的对象
sharedElement:一个view对象,用来和新的activity中的一个view对象产生动画
sharedElemetId:新的activity中的view的Id,这个view是用来和原始activity中的view产生动画的
效果是:原始activity中的一个view随着新activity的慢慢启动而移动到新的activity中,实现补间动画
public void screenTransitAnim(View v,int id) {
ActivityOptionsCompatICS options = ActivityOptionsCompatICS.
makeSceneTransitionAnimation(this, v,id);
ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
}
(5)public static ActivityOptionsCompatICS makeSceneTransitionAnimation(Activity activity,
Pair<View, Integer>... sharedElements)
参数:
activity:当前的activity
sharedElements:Pair对象,上面的一个方法是实现单一view的动画,这里可以有多个view对象进行动画
screenTransitAnimByPair(
Pair.create((View)orginalImageView, R.id.target_imageView),
Pair.create((View)orginalTextView, R.id.target_textView),
Pair.create((View)chromeIView, R.id.target_chrome_imageView));
@SuppressWarnings("unchecked")
public void screenTransitAnimByPair(Pair<View, Integer>... views) {
ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeSceneTransitionAnimation(
MainActivity.this, views);
ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
}
二、ActivityCompatICS
这个类仅仅提供了启动activity的方法,很简单就一个静态方法
public static void startActivity(Activity activity, Intent intent, Bundle bundle)
传入的bundle是ActivityOptionsCompatICS通过toBundle()方法产生的bundle对象
三、TransitionCompat
这个类是用在新的activity中接收动画的,在新的activity的setContentView()后写
TransitionCompat.startTransition(this, R.layout.activity_target);即可。
这里的参数一个是activity对象,一个是当前activity的布局文件
在新activity的onBackPressed()方法中写上TransitionCompat.finishAfterTransition(this);就可以实现退出时的动画了。
当然这个类提供了各种设置方法:
TransitionCompat.addListener(transitionListener);
TransitionCompat.addViewAnimListener(viewAnimListener);
TransitionCompat.setEnterTransition(new SceneFade(this, true));// use to scale Up animation
TransitionCompat.setExitTransition(animation)//在onBackPressed中设置
TransitionCompat.setAnimDuration(300);// default
TransitionCompat.setAnimStartDelay(0);// default
TransitionCompat.setTimeInterpolator(new AccelerateDecelerateInterpolator());// default
1.设置屏幕动画监听器
2.设置view动画的监听器(用于bitmap,sharedElements动画),监听器中可以得到view的对象和id
3.设置屏幕进入时的效果,这里传入的是个继承自TransitionAnims的实现类,这个我们下面再说
4.设置屏幕退出时的效果,这里传入的是个继承自TransitionAnims的实现类
5.设置动画的持续时间
6.设置动画的延迟时间
7.设置动画的变化效果
四、TransitionAnims
这个TransitionAnims是一个实现屏幕动画的抽象类,里面实现了各种初始化和收尾操作,并且添加了常用的监听器。如果我们想自己对屏幕进行动画效果的设定,只需要继承这个类然后实现方法即可。
package com.example.activityoptionsjbtest; import android.app.Activity; import com.kale.activityoptions.transition.TransitionAnims; public class SceneAnimTest extends TransitionAnims{ public SceneAnimTest(Activity activity) {
super(activity);
// TODO 自动生成的构造函数存根
} @Override
public void playScreenEnterAnims() {
// TODO 自动生成的方法存根 } @Override
public void playScreenExitAnims() {
// TODO 自动生成的方法存根 } }
我们来看看这个类中我们可以得到什么东西。
getActivity();//得到要启动动画的activity
getAnimsDuration();//得到通过transitionCompatICS设置的动画持续时间
getAnimsInterpolator();//得到通过transitionCompatICS设置的动画效果
getBackground();//得到当前activity默认的背景图片,这个是开源项目中默认设置的,是一个#eeeeee的drawable。仅仅用于收尾操作
getAnimsStartDelay();////得到通过transitionCompatICS设置的动画延迟时间
//废弃//getIsEntireScreenAnim();////得到当前是否是让整个屏幕执行动画,如果不是那么就是让activity的actionbar下方的view执行动画
getSceneRoot();//重要:执行动画的view对象。
这里面还有一个动画监听器,我们继承这个类后可以直接用这个监听器来实现动画监听操作。比如原始项目中用于屏幕渐变操作的类就用到了这个监听器。如果不用这个监听器,那么transitionCompatICS设置的屏幕监听器是监听不到动画的。
其中还有两个收尾方法:
enterAnimsEnd(); // 在进入动画结束后请自行调用
exitAnimsEnd(); // 在退出动画结束后请自行调用
片段:
AnimatorSet set = new AnimatorSet();
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(getSceneRoot(), "alpha", fromAlpha, toAlpha);
set.addListener(new TransitionAnimsListener() {
@Override
public void onAnimationEnd(Animator animator) {
// TODO 自动生成的方法存根
super.onAnimationEnd(animator);
if (isEnter) {
enterAnimsEnd();
}else {
exitAnimsEnd();
}
}
});
原始项目中使用这个类的例子(渐变效果):
package com.kale.activityoptions.anim; import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity; import com.kale.activityoptions.transition.TransitionAnims; public class SceneFade extends TransitionAnims{ public SceneFade(Activity activity) {
super(activity);
// TODO 自动生成的构造函数存根
} public void playScreenAnims(final boolean isEnter) {
float fromAlpha,toAlpha;
if (isEnter) {
fromAlpha = 0f;
toAlpha = 1f;
}else {
fromAlpha = 1f;
toAlpha = 0f;
} // TODO 自动生成的方法存根
AnimatorSet set = new AnimatorSet();
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(getSceneRoot(), "alpha", fromAlpha, toAlpha);
set.addListener(new TransitionAnimsListener() {
@Override
public void onAnimationEnd(Animator animator) {
// TODO 自动生成的方法存根
super.onAnimationEnd(animator);
if (isEnter) {
enterAnimsEnd();
}else {
exitAnimsEnd();
}
}
});
set.play(alphaAnim);
set.setDuration(getAnimsDuration());
set.setStartDelay(getAnimsStartDelay());
set.setInterpolator(getAnimsInterpolator());
set.start();
} @Override
public void playScreenEnterAnims() {
// TODO 自动生成的方法存根
playScreenAnims(true);
} @Override
public void playScreenExitAnims() {
// TODO 自动生成的方法存根
playScreenAnims(false);
} }
设置方式:
TransitionCompat.setEnterTransition(new SceneFade(this, true));
@Override
public void onBackPressed() {
TransitionCompat.setExitTransition(new SceneFade(this, true));
// 这段代码必须放在TransitionCompat各种设置之后
TransitionCompat.finishAfterTransition(this);
}
五、小例子
MainActivity.java
package com.example.activityoptionsjbtest; import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.Pair;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; import com.kale.activityoptions.ActivityCompatICS;
import com.kale.activityoptions.ActivityOptionsCompatICS; public class MainActivity extends ActionBarActivity {
private ImageView chromeIView;
private Intent intent; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); intent = new Intent(MainActivity.this, TargetActivity.class);
chromeIView = (ImageView)findViewById(R.id.chrome_imageView); }
public void buttonListener(View views) {
switch (views.getId()) {
case R.id.thumbnail_button:
thumbNailScaleAnim(chromeIView);
break;default:
break;
}
}public void thumbNailScaleAnim(ImageView view) {
view.setDrawingCacheEnabled(true);
Bitmap bitmap = view.getDrawingCache();
ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeThumbnailScaleUpAnimation(
view, bitmap, 0, 0);
// Request the activity be started, using the custom animation options.
ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
//view.setDrawingCacheEnabled(false);
}
}
TargetActivity.java
package com.example.activityoptionsjbtest; import android.animation.Animator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation; import com.kale.activityoptions.anim.SceneFade;
import com.kale.activityoptions.anim.ViewAnimationListenerAdapter;
import com.kale.activityoptions.transition.TransitionCompat;
import com.kale.activityoptions.transition.TransitionListenerAdapter; public class TargetActivity extends Activity{ boolean isShowed = false; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_target);// 这段代码必须放在TransitionCompatICS各种设置之后
TransitionCompat.startTransition(this, R.layout.activity_target);
} @Override
public void onBackPressed() {
//super.onBackPressed();// 这段代码必须放在TransitionCompatICS各种设置之后
TransitionCompat.finishAfterTransition(this); }
}
这个项目兼容到3.1,对于2.x我试着兼容了一部分,但还有几个小问题。所以就只做了一个高版本的。毕竟目前4.x才是主流。
下载地址:https://github.com/tianzhijiexian/ActivityOptionsICS
用开源项目ActivityOptionsICS让ActivityOptions的动画实现兼容的更多相关文章
- 用开源项目JazzyViewPager实现ViewPager切换动画
JazzyViewPager这个项目可以让viewpager有各种绚丽的动画,而且还可以自由扩展.但从官网下载的lib导入时会出现找不到视图的问题,不知道是不是我人品不行,所以我就自己写了lib.总之 ...
- iOS - 开源框架、项目和学习资料汇总(动画篇)
动画 1. Core Animation笔记,基本的使用方法 – Core Animation笔记,基本的使用方法:1.基本动画,2.多步动画,3.沿路径的动画,4.时间函数,5.动画组.2. awe ...
- Android github上开源项目、酷炫的交互动画和视觉效果地址集合
Android上开源的酷炫的交互动画和视觉效果:http://blog.csdn.net/u013278099/article/details/50323689 Awesome-android-ui: ...
- 59.Android开源项目及库 (转)
转载 : https://github.com/Tim9Liu9/TimLiu-Android?hmsr=toutiao.io&utm_medium=toutiao.io&utm_so ...
- Android开源项目及库搜集
TimLiu-Android 自己总结的Android开源项目及库. github排名 https://github.com/trending,github搜索:https://github.com/ ...
- iOS开源项目周报0105
由OpenDigg 出品的iOS开源项目周报第四期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. He ...
- iOS开源项目周报1222
由OpenDigg 出品的iOS开源项目周报第二期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. io ...
- OpenDigg前端开源项目周报1219
由OpenDigg 出品的前端开源项目周报第二期来啦.我们的前端开源周报集合了OpenDigg一周来新收录的优质的前端开发方面的开源项目,方便前端开发人员便捷的找到自己需要的项目工具等.react-f ...
- iOS开源项目周报1215
由OpenDigg 出品的iOS开源项目周报第一期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. PY ...
随机推荐
- CentOS安装mysql*.rpm提示conflicts with file from package的解决办法
看到“conflicts”,是产生冲突了,文件“/usr/share/mysql/charsets/*”需要MySQL-server-5.6.19-1.linux_glibc2.5.x86_64版本的 ...
- 开源VS商用,IBM区块链从Hyperledger到商用平台之道 | 对话IBM高级架构师【 笔记】(转)
https://www.toutiao.com/a6520005731867951619/?tt_from=weixin&utm_campaign=client_share× ...
- .NET Core Entity使用Entity Framework Core链接数据库
首先安装Nuget包 Install-package Microsoft.EntityFrameworkCore Install-package Microsoft.EntityFrameworkCo ...
- WPF 使用HttpListener搭建本地web服务器
准备工作 using Micro.Listener 类(Micro.Listener.dll)下载 调用示例:一.启动服务:new Micro.Listener.ListenerSync(8080). ...
- JmsTemplate sendAndReceive 设置超时
通过调用sendAndReceive方法,实现发送消息之后可以同步接收返回信息. Message replyMsg = this.jmsQueueTemplate.sendAndReceive(new ...
- Script Browser & Script Analyzer 1.3更新发布
感谢Windows PowerShell MVP Kirk Munro.Laurent Dardenne在过去三个星期内为我们提出的各种想法和建议.针对这些的建议,我们对Script Browser ...
- 12C -- ORA-12850: 无法在所有指定实例上分配从属进程: 需要 2, 已分配 1
使用客户端连接到oracle 12.2.0.1 rac数据库,报以下错误信息: ORA-12850: 无法在所有指定实例上分配从属进程: 需要 2, 已分配 1 因为没有mos账号,只好谷歌一下了.找 ...
- 实战c++中的vector系列--vector<unique_ptr<>>初始化(全部权转移)
C++11为我们提供了智能指针,给我们带来了非常多便利的地方. 那么假设把unique_ptr作为vector容器的元素呢? 形式如出一辙:vector<unique_ptr<int> ...
- 委托到Lambda的进化: ()=> {} 这个lambda表达式就是一个无参数的委托及具体方法的组合体。
1.原始的委托 (.net 1.0) using System; using System.Collections.Generic; using System.ComponentModel; usin ...
- 物联网架构成长之路(20)-申请免费SSL证书
0.前言 今天域名备案申请下来了,接下来就是申请个SSL证书,现在普通的网站没有SSL都不好意思见人了.可是稍微好点的企业级SSL证书还是比较贵的.不过还好有免费的可以用.只不过要定时去续时间.这个不 ...