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

时间:2012-12-10 21:55:37

标签: android android-fragments android-animation fragmenttransaction

我使用show / hide来显示占据屏幕一部分的片段。出于某种原因,当显示片段时,slide_in_left动画播放,但是当片段被隐藏时没有动画时,片段就会消失。我尝试对slide_in_leftexit使用enter动画,这没有用。当将代码跟踪到支持包中时,动画确实被创建并且正在执行用于显示它的代码。 (我跟踪了.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时,它变为可见并在水平线性布局内共享空间(两个片段占据的屏幕宽度由weight参数决定)。

6 个答案:

答案 0 :(得分:20)

尝试使用 setCustomAnimations(int enter,int exit,int popEnter,int popExit) 代替 setCustomAnimations(int enter,int exit) 当您调用popupbackstack退出动画时不会被称为

答案 1 :(得分:3)

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

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

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

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

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

你可能要玩。 .add(Fragment)等待它被添加,然后调用.remove(Fragment)删除旧片段,这样新片段就会被物理放置在现有片段之上。

答案 2 :(得分:2)

  supportFragmentManager.beginTransaction()
     .setCustomAnimations(R.anim.enter_slide_up, R.anim.exit_slide_down,R.anim.enter_slide_up, R.anim.exit_slide_down)
     .add(R.id.nav_host_fragment, fragment)
        .addToBackStack(BACK_STACK)
        .commit()

答案 3 :(得分: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

我希望它有所帮助!

答案 4 :(得分: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 :(得分:-5)

我能够使用.replace代替.add

来使用退出动画
ft.replace(R.id.container, new MyFragment());