CustomAnimations on FragmentTransaction not workin

2019-06-13 15:52发布

问题:

My FragmentActivity displays one Fragment at the beginning and a second when I press a Button. Until here, it's easy. But I got one problem with the animations.
I add the second fragment with:

mTChild.add(R.id.container, mFragChild).addToBackStack(null).commit();  

And to make it more "alive", I declare a CustomAnimations before adding the Fragment, it looks like this:

mTChild.setCustomAnimations(R.anim.slide_in, R.anim.alpha_out, R.anim.alpha_in, R.anim.slide_out);  
mTChild.add(R.id.container, mFragChild).addToBackStack(null).commit();  

I used this method setCustomAnimations(int,int,int,int) (parameters: enter, exit, popBack enter, popBack exit) as you can see on setCustomAnimations Documentation. Just to understand my (basic) animations xml:

  1. slide_in > the new fragment slide from right to left.
  2. slide_out > back stack = fragment slide from left to right.
  3. alpha_out > the old fragment disappears with alpha 100 --> 0.
  4. alpha_in > back stack = old fragment appears with alpha 0 --> 100.

At this step, I got what I want a slide in/slide out from right for the new fragment which takes place above the old fragment. But the effect for the old fragment which normally stays behind and disappears/appears with the alpha not happens.

What I am doing wrong? Because, the CustomAnimations happens but not for the old fragment (which it not removed).
Thanks for your answers.

回答1:

I feel shame, I did a stupid mistake!

First of all:

Obviously I can't do this like I did, because the old fragment stays behind. So it can't make an out animation.

I answered at my own question when I asked it: "the old fragment (which it not removed)"... my god! So instead of:

mTChild.add(R.id.container, mFragChild).addToBackStack(null).commit();  

I should do:

// REPLACE (remove+add) and not ADD only !
mTChild.replace(R.id.container, mFragChild).addToBackStack(null).commit();  

If I want an out animation.


Nice effect:

I found an elegant way! Indeed, the goal was to keep the first Fragment visible, overlapping with a new Fragment (a ListView) and make the older less visible to 10% (for giving a shadow/under effect). I was wrong on the way to do this.

Inspired by SlidingMenu and this answer Generate an overlay slide in and move existing Fragment to left, I created a FrameLayout to add() (this time no doubt) the new Fragment which have a View to the left with a gradient background to make the shadow effect.
With this:

mTransaction.add(R.id.container, mChildA, null).hide(mChildA)
            .add(R.id.container2, mFrag, null).commit();  

And after, when I press my Button, I do as below:

mTChild.setCustomAnimations(R.anim.slide_in, 0, 0, R.anim.slide_out);  
mTChild.show(mChildA).addToBackStack(null).commit();

In fact, I have the slide in and the reverse effect with the BackStack, and I overlay my content with a shadow on the left side. The xml of my Fragment it's now:

<RelativeLayout
    android:layout_width="match_parent" android:layout_height="match_parent" >

    <View 
        android:id="@+id/shadowLeft"
        android:layout_width="50dip" android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:background="@drawable/fragment_shadow_left" />

    <ListView  
        android:id="@+id/list"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_toRightOf="@id/shadowLeft" />

</RelativeLayout>

Finally, I make the FrameLayout to "host" this layout above, with a background transparent and it works perfectly.
If someone wants to edit or give a better answer, I'm always listening. Hope this will be useful for someone who searches the same effect.



回答2:

Have you considered using the method called "replace" instead of "add" in order to change your fragments?