退出动画不工作; FragmentTransaction自定义动画不适用于隐藏

问题描述 投票:9回答:5

我使用show / hide来显示占据屏幕一部分的片段。出于某种原因,当片段被显示时,slide_in_left动画播放,但是当片段被隐藏时没有动画时,片段就会消失。我尝试使用slide_in_left动画为exitenter,这没有帮助。当将代码跟踪到支持包中时,动画确实被创建并且正在执行用于显示它的代码。 (我跟踪了.hide电话)

FragmentManager fm = _activity.getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.my_fragment);
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left);
if (fragment.isHidden()) {
    ft.show(fragment);
    fragment.setUserVisibleHint(true);
} else {
    ft.hide(fragment);
}
ft.commit();

以防万一这里是slide_out_left动画的xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="-50%p"
        android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
        android:duration="@android:integer/config_mediumAnimTime" />
</set>

编辑:问题可能与my_fragment与另一个包含webview的片段共享屏幕宽度这一事实有关。当为my_fragment执行.show时,它变为可见并在水平线性布局内共享空间(两个片段中的每一个占用多少屏幕宽度由权重参数确定)。

android android-fragments android-animation fragmenttransaction
5个回答
3
投票

就个人而言,这是碎片动画的zPosition的一个错误。

你看到的是新片段“出现”,这是因为新片段附加在当前片段下面。

因此,当试图为现有片段的“Over the top”片段设置动画时,似乎没有任何事情发生,那么新的片段就会“出现”。

我尝试了很多工作,玩zPosition(只影响windows而不是布局,因此对片段没有影响),onAnimationCreate()将根布局带到前面甚至动画开始和停止......似乎什么都不做。

所以在这个时间点没有为片段转换编写完整的自定义动画,它们现在有点儿麻烦。

你可能要玩。 .add(Fragment)等待它被添加,然后调用.remove(Fragment)删除旧片段,这样新片段实际上放在现有片段的顶部。


20
投票

尝试使用setCustomAnimations(int enter,int exit,int popEnter,int popExit)而不是setCustomAnimations(int enter,int exit)当你调用popupbackstack退出动画时不会被调用


1
投票

我认为它出现了同样的情况:

我有N个片段,我想有一个自定义动画,但我不想重新加载片段,所以做一个addremovereplace不是一个解决方案,并与show / hide我无法同步动画之间两个片段。

要修复它,我必须为每个片段使用FrameLayout。

这里的代码。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_above="@+id/main_bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/library"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <FrameLayout
            android:id="@+id/search"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <FrameLayout
            android:id="@+id/discover"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </FrameLayout>

    <com.roughike.bottombar.BottomBar
        android:id="@+id/main_bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        app:bb_tabXmlResource="@xml/main_bb_tabs"
        app:bb_inActiveTabColor="@color/taupegray"
        app:bb_activeTabColor="@color/green_apple"
        app:bb_showShadow="true"/>

</RelativeLayout>

然后控制要显示的片段:

private void showFragment(BaseFragment fragment) {
    Animation animation = AnimationUtils.loadAnimation(this,
                R.anim.slide_in_from_right);

    if (fragment instanceof DiscoverFragment) {
        mDiscoverContainer.bringToFront();
        mDiscoverContainer.startAnimation(animation);

        return;
    }

    if (fragment instanceof LibraryFragment) {
        mLibraryContainer.bringToFront();
        mLibraryContainer.startAnimation(animation);

        return;
    }

    if (fragment instanceof SearchFragment) {
        mSearchContainer.bringToFront();
        mSearchContainer.startAnimation(AnimationUtils.loadAnimation(animation);

        return;
    }
}

关键在于bringToFront

我希望它有所帮助!


0
投票

尝试使用转换。以下是我的项目中的示例:

private fun changeFragment(fragment: BaseFragment, addBackStack: Boolean) {
    // Set transitions
    fragment.enterTransition = Fade(Fade.IN).apply { duration = 800 }
    fragment.exitTransition = Slide(Gravity.TOP).apply { duration = 800 }
    // Your transaction below
    val fragmentTransaction = supportFragmentManager.beginTransaction()

    fragmentTransaction.replace(R.id.fragmentContainer, fragment)
    if (addBackStack) {
        fragmentTransaction.addToBackStack(fragment.javaClass.name)
    }
    fragmentTransaction.commit()
}

而且你也可以自己进行过渡:https://medium.com/@belokon.roman/custom-transitions-in-android-f8949870bd63


-5
投票

我能够使用.replace代替.add来使用退出动画

ft.replace(R.id.container, new MyFragment());
© www.soinside.com 2019 - 2024. All rights reserved.