Android Fragment 转场动画:退出动画在进入动画之上播放

11

我正在实现 Fragment 转场动画。

我的 exit 动画是

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:ordering="together">
    <objectAnimator
        android:propertyName="scaleX"
        android:valueType="floatType"
        android:valueFrom="1.0"
        android:valueTo="0.95"
        android:duration="300"/>

    <objectAnimator
        android:propertyName="scaleY"
        android:valueType="floatType"
        android:valueFrom="1.0"
        android:valueTo="0.95"
        android:duration="300"/>

    <objectAnimator
        android:propertyName="x"
        android:valueType="floatType"
        android:valueFrom="0"
        android:valueTo="10dp"
        android:duration="300"/>
</set>

进入动画为:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="x"
    android:valueType="floatType"
    android:valueFrom="1280"
    android:valueTo="0"
    android:duration="400"/>

交易是这样创建的:

fragmentManager.beginTransaction()
            .setCustomAnimations(enter, exit, popEnter, popExit)
            .replace(CONTENT_CONTAINER_ID, newFragment)
            .addToBackStack(null)
            .commit();

在正常的动画速度下,由于动画持续时间短,不需要的效果几乎是不可见的,但当您放慢它们的速度时,您可以清楚地看到z-order是错误的。

进入片段动画位于退出片段动画之下。是否有解决方法来解决这个问题?


这个解决方案对我很有效。 - wudizhuo
4个回答

4
我认为您可以尝试以下方法作为解决办法。
fragmentTr.setCustomAnimations(enter, exit);
fragmentTr.hide(currentFragment);
fragmentTr.add(containerId, newFragment, "aTag");
fragmentTr.show(newFragment);
fragmentTr.commit();

不要使用replace()。我尝试了上述方法,它有效。 希望这可以帮助。

是的,这种做法有点效果,但我的导航比较棘手,有自定义的后退堆栈,这会破坏它... - Martynas Jurkus
1
向他人提示:顺序也很重要。我在显示后设置了自定义动画...这不是一个好主意。 - Nilzor

2

这可能已经过时了,但我刚遇到了同样的问题。我通过在我的XML中定义两个内容区域来解决它,例如:

<FrameLayout>
   <FrameLayout id="@+id/oldFragment" />
   <FrameLayout id="@+id/newFragment" />
</FrameLayout>

我会将第一个片段加载到oldFragment中,我的事务如下所示:
getActivity().getSupportFragmentManager()
        .beginTransaction()
        .remove(old_frag)
        .add(R.id.newFragment, new_frag)
        .addToBackStack(null)
        .commit();

希望这可以帮到你。

0

我知道这已经太老了,但我在使用Android Jetpack时遇到了同样的问题。

这是关于Android Jetpack和导航图的答案。

  1. 在navigation.xml中设置动画
  2. <fragment
    android:id="@+id/specifyAmountFragment"
    android:name="com.example.buybuddy.buybuddy.SpecifyAmountFragment"
    android:label="fragment_specify_amount"
    tools:layout="@layout/fragment_specify_amount">
    <action
        android:id="@+id/confirmationAction"
        app:destination="@id/confirmationFragment"
        app:enterAnim="@anim/slide_in_right"
        app:exitAnim="@anim/slide_out_left"
        app:popEnterAnim="@anim/slide_in_left"
        app:popExitAnim="@anim/slide_out_right" />
    
  3. 添加动画资源

slide_in_left.xml

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

slide_out_left.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="200"/>
</set>

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="200"/>
</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="200"/>
</set>

其他有用的答案 更多详细信息请参阅Android开发者文档

其他示例动画:


-1

对我来说可行,在动画中添加这一行

android:interpolator="@android:anim/linear_interpolator"

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