Activity过度动画应用

来源:互联网 发布:js调用手机相册插件 编辑:程序博客网 时间:2024/04/30 20:05

这里介绍一下Activity之间共享元素过渡动画的使用,首先看两张效果图:

 

可以看到非常的酷炫。关于Activity的过渡动画不了解的同学可以先了解一下这篇文章:Android 5.0学习之Activity过渡动画

关于共享元素跳转的步骤大致如下:


共享元素跳转:

为了使有一个共享元素的两个activities间使用过渡动画:

1.在你的主题中启用窗口内容过渡

2.在你的主题样式中指定共享元素的过渡

3.定义你的过渡动画为XML资源

4.使用android:transitionName属性给两个布局中的共享元素指定一个相同的名字(名字一定不要写错)

5.使用ActivityOptions.makeSceneTransitionAnimation() 方法

首先在主题里面添加下面属性:

        <item name="android:windowContentTransitions">true</item>        <item name="android:windowAllowEnterTransitionOverlap">false</item>        <item name="android:windowAllowReturnTransitionOverlap">false</item>

android:windowContentTransitions用于开启窗口内容转换动画,另外两个属性设置false是为了让进出动画不重叠。
然后在主题样式中指定共享元素的过渡动画:(也可以不设置,采用系统默认的)

        <item name="android:windowSharedElementEnterTransition">@transition/dribbble_shot_shared_enter</item>        <item name="android:windowSharedElementReturnTransition">@transition/dribbble_shot_shared_return</item>

这两个属性是指定共享元素的进出动画。动画的xml格式如下:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">      <explode/>      <changeBounds/>      <changeTransform/>      <changeClipBounds/>      <changeImageTransform/>  </transitionSet>

也可以通过代码来设置:

        Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.changebounds_with_arcmotion);        getWindow().setSharedElementEnterTransition(transition);

值得注意的是上面的第四点,android:transitionName的名称必须一样。

先看下如何启动动画:

        ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(mActivity, pairs);        mActivity.startActivity(intent, transitionActivityOptions.toBundle());

可以看到上面有个pairs,它是一个元素类型为Pair<View, String>的数组,View代表指定动画的控件,String代表transitionName,这个名称必须和xml中指定控件的android:transitionName名称一样,如下:

    private void transitionToActivity(Class target, MyHolder viewHolder, Student student) {        final Pair<View, String>[] pairs = TransitionHelper.createSafeTransitionParticipants(mActivity, false,                new Pair<>(viewHolder.listItemBinding.sampleIcon, mActivity.getString(R.string.square_blue_name)),                new Pair<>(viewHolder.listItemBinding.sampleName, mActivity.getString(R.string.sample_blue_title)));        startActivity(target, pairs, student);    }

可以看到这里有两个Pair元素,一个是ImageView类型的sampleIcon,transitionName为square_blue_name;一个是TextView类型的sampleName,transitionName为sample_blue_title。下面看下xml里面是如何对应的:

        <ImageView            android:id="@+id/sample_icon"            style="@style/MaterialAnimations.Icon.Big"            android:src="@drawable/circle_24dp"            android:transitionName="@string/square_blue_name"            app:colorTint="@{student.color}" />
这个控件对应Pair第一个元素,可以看到类型和transitionName都一样。

            <TextView                android:id="@+id/title"                style="@style/MaterialAnimations.TextAppearance.Title.Inverse"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_gravity="center_vertical|start"                android:transitionName="@string/sample_blue_title"                android:text="@{student.name}" />

这个控件对应Pair数组的第二个元素,同样transitionName必须一样。

最后看下一个生成Pair数组的帮助类:

/** * Helper class for creating content transitions used with {@link android.app.ActivityOptions}. */class TransitionHelper {    /**     * Create the transition participants required during a activity transition while     * avoiding glitches with the system UI.     *     * @param activity The activity used as start for the transition.     * @param includeStatusBar If false, the status bar will not be added as the transition     *        participant.     * @return All transition participants.     */    public static Pair<View, String>[] createSafeTransitionParticipants(@NonNull Activity activity,                                                          boolean includeStatusBar, @Nullable Pair... otherParticipants) {        // Avoid system UI glitches as described here:        // https://plus.google.com/+AlexLockwood/posts/RPtwZ5nNebb        View decor = activity.getWindow().getDecorView();        View statusBar = null;        if (includeStatusBar) {            statusBar = decor.findViewById(android.R.id.statusBarBackground);        }        View navBar = decor.findViewById(android.R.id.navigationBarBackground);        // Create pair of transition participants.        List<Pair> participants = new ArrayList<>(3);        addNonNullViewToTransitionParticipants(statusBar, participants);        addNonNullViewToTransitionParticipants(navBar, participants);        // only add transition participants if there's at least one none-null element        if (otherParticipants != null && !(otherParticipants.length == 1                && otherParticipants[0] == null)) {            participants.addAll(Arrays.asList(otherParticipants));        }        return participants.toArray(new Pair[participants.size()]);    }    private static void addNonNullViewToTransitionParticipants(View view, List<Pair> participants) {        if (view == null) {            return;        }        participants.add(new Pair<>(view, view.getTransitionName()));    }}

仔细看下代码,其实比较容易理解。就是从DecorView中获取statusBar和navBar,将它们也添加到共享元素数组当中,这样可以提高用户体验。


对于共享元素的细节可参考如下文章:

深入理解 Shared Element Transition

参考源码可以在这里下:

Material-Animations


1 0