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

Android Study Material Design 十七 之 转场动画

2017-12-28 23:35 941 查看
LZ-Says:最近的状态浑浑噩噩,很是不爽,得好好调节下自己~



前言

最近的状态个人觉得很不满意,今天通过一篇简短博文重新找回自己~

而今天,我们一起来聊聊Android转场动画。

那么,所谓的“转场动画”,究竟是个什么鬼?

简单可以理解为俩个Activity之间切换过程中的效果。


接下来,通过代码+效果图方式,让你直观了解并掌握有关转场动画小姿势~

本文目标

通过依次举例包括简要查看系统源码,让阅读本文的你,对Android中的转场动画掌握更加自如~

效果展示

有的着急的小伙伴就会说了:



不急不急,马上就来~



车已启动,一起来~

一、overridePendingTransition回顾

首先,我们回顾下,我们之前是如何设置Activity切换过程中的动画,毫无疑问,通过overridePendingTransition,那么我们一起来看一下实现:

overridePendingTransition(int enterAnim, int exitAnim):

enterAnim: Activity进入动画;

exitAnim: Activity退出动画。

那么我们一起来看,如下效果如何实现?



基于上面给出的关于overridePendingTransition的使用,我们只需要引用系统已经写好的文件即可达到效果,不信你往下看:

public void getOverridePendingTransition(View view) {
startActivity(new Intent(selfActivity, OverridePendingTransitionActivity.class));
overridePendingTransition(
android.R.anim.fade_in,
android.R.anim.fade_out);
}


这里需要注意:

这个overridePendingTransition需要放置在startActivity或者finish之后。


二、通过Style设置切换动画

我们先来看下通过Style设置之后的效果:



此种方式比较nice,首先,需要创建values-v21目录,其次,在此目录下设置android:windowAnimationStyle,最后设置给要使用的Activity即可。

除此之外,我们还需要编写我们的anim文件,如上图,右进右出,如下:

slide_in_right: 设置从屏幕右侧进入

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:fromXDelta="100%p"
android:toXDelta="0" />
</set>


slide_out_right:设置从屏幕右侧出去

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_mediumAnimTime"
android:fromXDelta="0"
android:toXDelta="-50%p" />
</set>


其次,这里需要为大家简述下关于Style里面我们有用的几个小属性:

activityOpenEnterAnimation: 设置打开新的Activity并进入新的Activity展示的动画;

activityOpenExitAnimation: 设置打开新的Activity并销毁之前的Activity展示的动画;

activityCloseEnterAnimation: 设置关闭当前Activity进入上一个Activity展示的动画;

activityCloseExitAnimation: 设置关闭当前Activity时展示的动画

<style name="styleActivity" parent="AppTheme">
<item name="android:windowAnimationStyle">@style/activityStyleAnim</item>
</style>

<style name="activityStyleAnim">
<item name="android:activityOpenEnterAnimation">@anim/slide_in_right</item>
<item name="android:activityOpenExitAnimation">@anim/slide_out_right</item>
</style>


为你的Activity设置可通过主题去引用即可:

<activity
android:name=".activity.StyleActivity"
android:theme="@style/styleActivity" />


三、通过ActivityOptions/ActivityOptionsCompat共享元素实现

ActivityOptions,谷歌提供给我们在Activity切换时的转场动画类,缺陷是仅支持Api 21以上,也就是Android 5.0以上。

So,针对如上的限制,谷歌推出兼容包ActivityOptionsCompat,这个包的主要作用就是为我们省去了对当前系统版本的判断。



系统源码如下:

@RequiresApi(16)
private static ActivityOptionsCompat createImpl(ActivityOptions options) {
if (Build.VERSION.SDK_INT >= 24) {
return new ActivityOptionsCompatApi24Impl(options);
} else if (Build.VERSION.SDK_INT >= 23) {
return new ActivityOptionsCompatApi23Impl(options);
} else {
return new ActivityOptionsCompatApi16Impl(options);
}
}


接着,我们来看下关键方法参数所代表的含义:

makeSceneTransitionAnimation(Activity activity,View sharedElement, String sharedElementName):设置单个共享元素

Activity activity: 当前Activity;

View sharedElement: 设置共享元素的View;

String sharedElementName: 设置共享元素的名称;

既然有设置单个共享元素,那相对应的也有设置多个共享元素:

makeSceneTransitionAnimation(Activity activity,Pair《View, String>… sharedElements):设置多个共享元素

Activity activity: 当前Activity;

Pair《View, String>… sharedElements: 要设置共享元素的View;

要使用转场动画,首先需要做的就是告诉Activity支持(允许)使用转场动画,那么如何通知呢?俩种方式,如下:

方式一:代码设置

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);


方式二:style设置

<item name="android:windowContentTransitions">true</item>


这里LZ再次对使用转场动画需要注意点叙述一次,以便加深记忆:

首先,需要设置Activity允许使用转场动画;

其次,切换的俩个Activity中的共享元素View都需要设置android:transitionName,且设置的name要一样

那么接下来我们先来看一组单个共享元素实例:



实现步骤如下:

设置当前Activity允许转场动画;

布局中设置transitionName,记得切换的俩个Activity的transitionName需要设置为一致;

通过ActivityOptionsCompat兼容包设置转场动画。

关键代码如下:

设置允许转场

@Override
protected void onCreate(Bundle savedInstanceState) {
// 设置允许使用转场动画 此属性同样可以在style设置
// <item name="android:windowContentTransitions">true</item>
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}


设置transitionName

MainActivity-Layout:

<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="getActivityOptions"
android:text="使用ActivityOptions跳转Activity动画"
android:textAllCaps="false"
android:transitionName="activityOption" />


OptionActivity-Layout:

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/img1"
android:scaleType="fitXY"
android:transitionName="activityOption" />


跳转下一页时,绑定共享元素:

public void getActivityOptions(View view) {
Button btn = findViewById(R.id.btn);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat
.makeSceneTransitionAnimation(
this, // 当前Activity
btn, // 共享元素View
"activityOption"); // 共享元素名称
Intent intent = new Intent(selfActivity, ActivityOptionsCompatActivity.class);
startActivity(intent, optionsCompat.toBundle());
}


掌握了设置单个共享元素,多个相对来说也是很是Easy。下面一句话概括了。

设置多个共享元素,唯一不变的是需要指定transitionName,一一对应。

其次,通过实例化Pair对象去添加共享元素or直接通过Pair去创建而添加共享元素即可。


关键代码如下:

public void getActivityOptionsMore(View view) {
Button btn = findViewById(R.id.btn1);
ImageView iv = findViewById(R.id.img1);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat
.makeSceneTransitionAnimation(
this,
Pair.create((View) btn, "btn1"),
new Pair<View, String>(iv, "img1")
);
Intent intent = new Intent(selfActivity, ActivityOptionsMoreActivity.class);
startActivity(intent, optionsCompat.toBundle());
}


实现的效果也很nice:



当LZ点击返回的时候,同样也是以转场动画效果回归,那么它究竟在哪儿实现了呢?

当用户按下返回键时,执行下面方法:

@Override
public void onBackPressed() {
super.onBackPressed();
}


接着瞧内部:

public void onBackPressed() {
if (mActionBar != null && mActionBar.collapseActionView()) {
return;
}
FragmentManager fragmentManager = mFragments.getFragmentManager();
if (fragmentManager.isStateSaved() || !fragmentManager.popBackStackImmediate()) {
finishAfterTransition(); // 过渡之后finish
}
}


/**
* Reverses the Activity Scene entry Transition and triggers the calling Activity
* to reverse its exit Transition. When the exit Transition completes,
* {@link #finish()} is called. If no entry Transition was used, finish() is called
* immediately and the Activity exit Transition is run.
* @see android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, android.util.Pair[])
*/
public void finishAfterTransition() {
if (!mActivityTransitionState.startExitBackTransition(this)) {
finish();
}
}


以下三点,乃是谷歌为我们提供好的,直接拿过来使用就OK~

四、滑动(Slide)使用

public void getActivityOptionSlide(View view) {
Slide slide = new Slide();
slide.setDuration(800);
getWindow().setExitTransition(slide);
getWindow().setEnterTransition(slide);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(selfActivity);
Intent intent = new Intent(selfActivity, ActivityOptionsCompatActivity.class);
startActivity(intent, optionsCompat.toBundle());
}


效果如下:



五、展开(Explode)使用

public void getActivityOptionsExplode(View view) {
Explode explode = new Explode();
explode.setDuration(800);
getWindow().setExitTransition(explode);
getWindow().setEnterTransition(explode);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(selfActivity);
Intent intent = new Intent(selfActivity, ActivityOptionsCompatActivity.class);
startActivity(intent, optionsCompat.toBundle());
}


效果如下:



六、渐变(Fade)使用

public void getActivityOptionsFade(View view) {
Fade fade = new Fade();
fade.setDuration(800);
getWindow().setExitTransition(fade);
getWindow().setEnterTransition(fade);
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(selfActivity);
Intent intent = new Intent(selfActivity, ActivityOptionsCompatActivity.class);
startActivity(intent, optionsCompat.toBundle());
}


效果如下:



GitHub查看地址

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

赞赏

if 感觉有所收获 不妨动动小指赞赏下LZ~

else 嗯哼,提裤子不认人啊~

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