滑动层活动动画Android

9

我想实现材料设计指南中描述的活动转换滑动层动画。

Material Transition

然而,到目前为止我所做的只是简单的slide_in和stay动画的组合,没有给我堆叠层次的效果。我该怎么做才能实现呢?

我的当前实现:

当活动开始时:

activity.overridePendingTransition(R.anim.slide_in_right, R.anim.stay);

在活动关闭时:

activity.overridePendingTransition(R.anim.stay, R.anim.slide_out_right);

slide_in_right.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator">
    <translate
        android:fromXDelta="100%p"
        android:toXDelta="0"
        android:duration="@android:integer/config_shortAnimTime" />
</set>

slide_out_right.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator">
    <translate
        android:fromXDelta="0"
        android:toXDelta="100%p"
        android:duration="@android:integer/config_shortAnimTime" />
</set>

stay.xml:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_shortAnimTime"
    android:fromYDelta="0%p"
    android:toYDelta="0%p" />

1
这个实现有什么问题? - MineConsulting SRL
1
@gauravsapiens,你找到答案了吗? - Mr.Noob
2个回答

7
我终于找到了这个问题的解决方案。它完美运行。
此答案中使用的重要组件:
- BackActivity = 后台活动 - FrontActivity = 滑动在前面的活动 - BackgroundView = 前台活动中的基础ViewGroup 解决方案是在关闭FrontActivity之前,对其布局进行动画处理。只有在将工具栏集成到布局中作为操作栏时才可能实现此目的!
我将在此处复制我的代码。我的动画是从底部滑入前面的活动,并再次滑出到底部,在前一个活动的前面消失。您可以通过改变动画来轻松获得任何方向的效果。
1)将FrontActivity滑入BackActivity上。 只需在从BackActivity启动FrontActivity时调用overridePendingTransition即可。
Intent intent = new Intent(activity, FrontActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.slide_in_bottom, 0);

slide_in_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="100%p"
    android:toYDelta="0%p"
    android:duration="@android:integer/config_mediumAnimTime"
    android:interpolator="@android:anim/decelerate_interpolator">
</translate>

2) 从FrontActivity返回BackActivity时,在关闭FrontActivity之前,将FrontActivity的布局进行动画处理!

我通过在FrontActivity的onOptionsSelected()onBackPressed()中调用以下方法来实现这一点。

private void animateOut() {
    Animation slideAnim = AnimationUtils.loadAnimation(this,R.anim.slide_out_bottom);
    slideAnim.setFillAfter(true);;
    slideAnim.setAnimationListener(new AnimationListener() {
        public void onAnimationStart(Animation paramAnimation) { }
        public void onAnimationRepeat(Animation paramAnimation) { }
        public void onAnimationEnd(Animation paramAnimation) { 
            finish();
            // if you call NavUtils.navigateUpFromSameTask(activity); instead, 
            // the screen will flicker once after the animation. Since FrontActivity is 
            // in front of BackActivity, calling finish() should give the same result.
            overridePendingTransition(0, 0);
        }
    });
    BackgroundView.startAnimation(slideAnim);
}

slide_out_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="0%p"
    android:toYDelta="100%p"
    android:duration="@android:integer/config_mediumAnimTime"
    android:interpolator="@android:anim/accelerate_interpolator">
</translate>

3) 现在我们需要确保 BackActivity 在动画退出时能够显示在 FrontActivity 后面。
我们需要使用透明主题来实现这一点。

styles.xml

<resources>

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- your theme -->
    </style>

    <style name="Theme.Transparent" parent="AppTheme">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

</resources>

4) 在manifest文件中给FrontActivity应用透明主题:

AndroidManifest.xml

<activity
      android:name=".FrontActivity"
      android:theme="@style/Theme.Transparent"
      android:parentActivityName=".BackActivity" />

5) 由于您的活动现在是透明的,您需要为BackgroundView添加一个背景。 标准背景有:

android:background="@android:color/background_light"
android:background="@android:color/background_dark"

front_activity.xml

<?xml version="1.0" encoding="utf-8"?>

<!-- This is BackgroundView and can be any ViewGroup -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:background="@android:color/background_light" >

    <android.support.v7.widget.Toolbar
        android:layout_height="@dimen/height_toolbar"
        android:layout_width="match_parent"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <!-- rest of layout -->

</FrameLayout>

就是这样。动画现在应该可以正常工作了。


编辑

我找到了一个不会闪烁的解决方案。动画看起来非常流畅。

当关闭FrontActivity时,调用finish而不是NavUtils.navigateUpFromSameTask(activity)。我已经在我的答案中进行了更改。


太棒了!!运行得很好...不要忘记从返回键事件中**删除super.onBackPress();**。它会阻止我的动画。 - Mangesh
1
有什么想法可以为'FrontActivity'创建阴影效果吗? - Mangesh

5
你可以通过覆盖活动之间的转换来实现所描述的行为。 我还在后面的活动中包含了一个淡出缩小的效果,以改善其外观:
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%p" android:toXDelta="0"
        android:duration="@android:integer/config_shortAnimTime"/>
</set>

slide_out_right.xml

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

fade_back.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale android:duration="@android:integer/config_shortAnimTime"
        android:pivotX="50.0%"
        android:pivotY="50.0%"
        android:fromXScale="1.0"
        android:toXScale="0.9"
        android:fromYScale="1.0"
        android:toYScale="0.9"/>
    <alpha android:duration="@android:integer/config_shortAnimTime"
        android:fromAlpha="1.0"
        android:toAlpha="0.7"/>
</set>

fade_forward.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale android:duration="@android:integer/config_shortAnimTime"
        android:pivotX="50.0%"
        android:pivotY="50.0%"
        android:fromXScale="0.9"
        android:toXScale="1.0"
        android:fromYScale="0.9"
        android:toYScale="1.0"/>
    <alpha android:duration="@android:integer/config_shortAnimTime"
        android:fromAlpha="0.7"
        android:toAlpha="1.0"/>
</set>

ParentActivity.java

在一个父类中,你可以包含可以重复使用的代码:

/* Activity transitions */

protected void slideInTransition() {
    overridePendingTransition(R.anim.slide_in_right, R.anim.fade_back);
}

protected void slideOutTransition() {
    overridePendingTransition(R.anim.fade_forward, R.anim.slide_out_right);
}

然后在活动开始时:

startActivity(intent);
slideInTransition();

对于回滚操作:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接