replace two fragments with each other using animation

1.9k Views Asked by At

I'm just a beginner to native android developing. I have an application in which I have a fragment inside of an activity. This fragment has a header, a footer and in the middle a FrameLayout to display other fragments XML of the Fragment:

<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>

To show the first fragment I'm using the 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();

This fragment should simply placed there at the start. After I clicked on the Accept button, the first fragment should slide out of the screen over the top and the new, second fragment should slide in coming from the bottom. I'm using at the moment this code to replace them:

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();

But for any reason the fragments are replaced and after that, the animation starts. While the animation is going on, the new fragment is sliding out of the screen upsides and the old fragment slides in from the botton. After the Animation is finished the new fragment is displayed.

My Code for the animations:

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>

I don't know how to fix it or what the reason is for this crazy replacement. Hope somebody could help. Thank you

2

There are 2 best solutions below

0
On BEST ANSWER

Here is the right solution:

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

Thats the start to place the first fragment into the defined <FrameLayout>

If you want to replace this childFragment with an other childFragment, then use:

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();

And as an Extra. If you want to control the BackButtonFunction, then you have to Overwrite the OnBackPressed function in the parentFragment with following code:

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

This method would replace the fargments with a custom animation,

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();
    }

Following would be the Animation resources to be placed in 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>