使用导航组件实现幻灯片动画

14

我正在使用JetPack导航组件在不同的片段之间进行导航。 我已在图形XML中为两个片段之间添加了滑动动画:

<action
    android:id="@+id/action_Fragment_to_DetailsFragment"
    app:enterAnim="@anim/slide_left"
    app:popEnterAnim="@anim/slide_right"
    app:destination="@id/DetailsFragment" />

问题是 - 因为我正在使用导航组件并且它使用fragmentManager.replace()而不是fragmentManager.add(),因此我看到的不是平滑动画,而是:
  1. 第一个片段消失了

  2. 第二个片段的动画被触发,并将新片段滑动到屏幕上

  3. 第二个片段出现在屏幕上。

因为两个屏幕上的内容不同,所以看起来很卡顿。我想要实现的是"像IOS一样",用户可以看到两层屏幕从彼此滑动。有没有办法在不支持"fragmentManager.add()"的导航组件中实现它?
我也尝试过
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"

但情况并没有好转。


1
我遇到了类似的问题。你能找到解决方案或变通方法吗? - Ashray Mehta
@AshrayMehta 我已经添加了答案。现在这就是我所有的内容。如果您有更好的答案,请告诉我。 - Rainmaker
@AshrayMehta 我找到了方法并发布了新答案。 - Rainmaker
3个回答

26

最终我找到了如何做到这一点的方法。

  1. 在图表中,设置动画效果:

<action
        android:id="@+id/action_DetailsFragment"
        app:enterAnim="@anim/slide_left"
        app:exitAnim="@anim/wait_anim"
        app:popEnterAnim="@anim/wait_anim"
        app:popExitAnim="@anim/slide_right"
        app:destination="@id/detailsFragment" />

  1. 创建动画:

    slide_left.xml

    <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:duration="300"
        android:fromXDelta="100%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="0%" />
</set>

slide_right.xml

    <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:duration="300"
        android:fromXDelta="0%"
        android:fromYDelta="0%"
        android:toXDelta="100%"
        android:toYDelta="0%" />
</set>

wait_anim.xml

    <?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300">
</translate>

  1. 为了让界面看起来更好,在DetailsFragment中添加如下代码:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) ViewCompat.setTranslationZ(getView()!!, 100f) }

  2. 你还可以添加sharedElementTransitions,让你的动画更加独特。


非常感谢!你节省了我的时间!“wait_anim”正是我正在寻找的 :) - ahuminskyi

5

如果有人想要使用进入和退出动画来实现此效果。

https://i.imgur.com/vBKZPsr.gif

<action
    android:id="@+id/action_sign_in_to_fragmentMemberValidate"
    app:destination="@id/fragmentMemberValidate"
    app:enterAnim="@anim/nav_slide_in_right"
    app:exitAnim="@anim/nav_slide_out_left"
    app:popExitAnim="@anim/nav_slide_out_right"
    app:popEnterAnim="@anim/nav_slide_in_left"/>

nav_slide_in_right.xml

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

nav_slide_out_left.xml

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

nav_slide_out_right.xml

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

nav_slide_in_left.xml

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

1

到目前为止,我已经成功地使用以下方法改进了动画效果:

  • SharedElement 用于屏幕的某些部分

  • 将透明度添加到动画中

  • 加快幻灯片动画的速度,使“空白区域”不那么明显

但仍然无法实现类似IOS的滑动动画。


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