手记

Android Study Material Design 十七

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设置切换动画

此种方式比较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要一样

实现步骤如下:

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

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

  3. 通过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());
    }

当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());
    }

原文链接:http://www.apkbus.com/blog-904057-76783.html

0人推荐
随时随地看视频
慕课网APP