13

我使用 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 的片段共享屏幕宽度的事实有关。当 .show 为 my_fragment 执行时,它变得可见并在水平线性布局中共享空间(两个片段中的每一个占用多少屏幕宽度由 weight 参数确定)。

4

5 回答 5

30

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

于 2014-09-26T06:24:51.293 回答
4

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

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

因此,当尝试对现有片段的“上方”片段进行动画处理时,似乎什么都没有发生,然后新片段就“出现”了。

我尝试了很多变通方法,使用 zPosition(只影响窗口而不影响布局,因此对片段没有影响),onAnimationCreate()将根布局放在前面,甚至在动画开始和停止时......似乎什么也没做。

因此,在没有为片段过渡编写完整的自定义动画的情况下,它们目前有点错误。

你可能不得不玩。.add(Fragment)等待它被添加,然后调用.remove(Fragment)删除旧片段,这样新片段就物理地放置在现有片段的顶部。

于 2013-02-20T10:55:32.493 回答
3

尝试改用过渡。这是我项目中的示例:

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

于 2019-04-23T07:11:09.823 回答
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()
于 2021-04-19T11:52:33.863 回答
2

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

我有 N 个片段,我想要一个自定义动画,但我不想重新加载片段,所以执行addand removeor areplace不是解决方案,并且使用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

我希望它有所帮助!

于 2017-05-15T20:38:39.767 回答