使用动画相互替换两个片段

replace two fragments with each other using animation

我只是本机 android 开发的初学者。我有一个应用程序,其中在 activity 中有一个片段。此片段有页眉、页脚和中间的 FrameLayout 以显示其他片段 XML 的片段:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".fragments.Fragment1">

<!-- Dummy item for focus at startup -->
<LinearLayout
    android:id="@+id/dummy_id"
    android:orientation="vertical"
    android:layout_width="0px"
    android:layout_height="0px"
    android:focusable="true"
    android:focusableInTouchMode="true" />


<FrameLayout
    android:id="@+id/header_section"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:padding="10dp"
        android:text="@string/vehicle"
        android:textAlignment="center"
        android:textColor="@color/dark_grey_text"
        android:textSize="@dimen/title_size" />

    <ImageButton
        android:id="@+id/closeBT"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_margin="6dp"
        android:background="@drawable/close_button_icon" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_gravity="top"
        android:layout_marginTop="52dp"
        android:background="@android:color/darker_gray" />

</FrameLayout>

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/area_for_fragments"
    android:layout_below="@+id/header_section"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp">

</FrameLayout>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="@color/white">

    <LinearLayout
        android:id="@+id/footerLL"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_below="@+id/bottom_separator_line"
        android:layout_marginTop="10dp"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:paddingLeft="30dp"
        android:visibility="gone">

        <Switch
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:text="@string/titular_infractor"
            android:textColor="@color/grey_text"
            android:textSize="@dimen/text_size"
            android:textStyle="bold" />

    </LinearLayout>


    <ImageButton
        android:id="@+id/accept_button"
        android:visibility="visible"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_alignRight="@+id/bottom_separator_line"
        android:layout_below="@+id/bottom_separator_line"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="33dp"
        android:layout_marginTop="-50dp"
        android:background="@drawable/accept_button_selector" />

    <ImageButton
        android:id="@+id/cancel_button"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_below="@+id/bottom_separator_line"
        android:layout_marginBottom="10dp"
        android:layout_marginRight="3dp"
        android:layout_marginTop="-50dp"
        android:layout_toLeftOf="@+id/edit_vehicle_accept_button"
        android:background="@drawable/cancel_button_selector"
        android:visibility="gone"/>

    <View
        android:id="@+id/bottom_separator_line"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_alignParentTop="true"
        android:layout_marginBottom="55dp"
        android:background="@android:color/darker_gray" />

</RelativeLayout>

为了显示我正在使用 childFragmentManager 的第一个片段:

final FragmentTransaction ft = getChildFragmentManager().beginTransaction();
    TestSearchFragment elf = new TestSearchFragment();
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    ft.replace(R.id.area_for_fragments, elf);
    ft.addToBackStack(null);
    ft.commit();

这个片段应该简单地放在开头。单击“接受”按钮后,第一个片段应滑出屏幕顶部,新的第二个片段应从底部滑入。我目前正在使用这段代码来替换它们:

FragmentTransaction ft2 = getChildFragmentManager().beginTransaction();
            TestDetailFragment elf2 = new TestDetailFragment();


            ft2.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up);
            ft2.replace(R.id.area_for_fragments, elf2);

            ft2.addToBackStack("TEST FRAGMENT TAG")
                    .commit();

但是由于任何原因片段被替换,然后动画开始。动画进行时,新片段从屏幕上方滑出,旧片段从底部滑入。动画完成后显示新片段。

我的动画代码:

Slide_in_up.xml

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

slide_out_up.xml

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

我不知道如何修复它,也不知道这个疯狂更换的原因是什么。 希望有人能帮忙。 谢谢

此方法将用自定义动画替换片段,

private void flipToFragment(Fragment showFragment, Fragment hideFragment){
        getFragmentManager()
                .beginTransaction()
                .setCustomAnimations(
                        R.anim.card_flip_right_in, R.anim.card_flip_right_out,
                        R.anim.card_flip_left_in, R.anim.card_flip_left_out)
                .hide(hideFragment)
                .show(showFragment)
                .commit();
    }

以下是要放置的动画资源 res/anim ,

  1. card_flip_left_in.xml
 <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Before rotating, immediately set the alpha to 0. -->
        <objectAnimator
            android:valueFrom="1.0"
            android:valueTo="0.0"
            android:propertyName="alpha"
            android:duration="0" />

        <!-- Rotate. -->
        <objectAnimator
            android:valueFrom="-180"
            android:valueTo="0"
            android:propertyName="rotationY"


android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />


    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>
  1. card_flip_left_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>
  1. card_flip_right_in.xml
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Before rotating, immediately set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>
  1. card_flip_right_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="-180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

这是正确的解决方案:

FragmentTransaction fragmentTransactionSearch = getChildFragmentManager().beginTransaction();
        fragmentTransactionSearch.add(childSearchFragment, "SEARCH");
        fragmentTransactionSearch.replace(R.id.area_for_fragments, childSearchFragment);
        fragmentTransactionSearch.commit();

这就是将第一个片段放入定义的 <FrameLayout>

的开始

如果你想用另一个childFragment替换这个childFragment,那么使用:

FragmentTransaction fragmentTransactionDetail = getChildFragmentManager().beginTransaction();
        fragmentTransactionDetail.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up, R.anim.slide_out_down, R.anim.slide_in_down);
        fragmentTransactionDetail.remove(childSearchFragment);
        fragmentTransactionDetail.add(childDetailFragment, "DETAIL");
        fragmentTransactionDetail.replace(R.id.area_for_fragments, childDetailFragment);
        fragmentTransactionDetail.addToBackStack("ShowDetail");
        fragmentTransactionDetail.commit();

并且作为额外的。如果你想控制BackButtonFunction,那么你必须用下面的代码覆盖parentFragment中的OnBackPressed函数:

 if(parentFragment.getChildFragmentManager().getBackStackEntryCount() > 0)
    {   this.getChildFragmentManager().popBackStack();   }