Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment lost transition animation after configuration change

I'm inserting Fragments into the Activity using this code:

public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    FragmentManager fm = getFragmentManager();
    String tag = "simple";

    Fragment fr = fm.findFragmentByTag(tag);
    if (fr == null)
    {
        SimpleFragment simpleFragment = new SimpleFragment(); 
        FragmentTransaction transaction = fm.beginTransaction();
        transaction.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out,
                                        android.R.animator.fade_in, android.R.animator.fade_out);
        transaction.add(R.id.main_layout, simpleFragment, tag);
        transaction.addToBackStack(tag);
        transaction.commit();
    }
}

Fragments code is:

public class SimpleFragment extends ListFragment 
{
    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
    {
        super.onActivityCreated(savedInstanceState);
        getView().setBackgroundColor(Color.YELLOW);
    }
}

When I pop the fragment from backstack via Back button just after launching, then everything is fine and I can see fade out animation. But if I rotate device and press Back button then fragment disappears without animation.

Is this Android behavior or I'm doing something wrong?

EDIT: It seems that after rotation FragmentManager didn't restores animations (enterAnim, exitAnim, popEnterAnim and popExitAnim) for BackStackEntry.

FragmentManager dump (without rotation):

Active Fragments in 4087d668:
  #0: SimpleFragment{408883b0 #0 id=0x7f050000 simple}
    mFragmentId=#7f050000 mContainerId#=7f050000 mTag=simple
    mState=4 mIndex=0 mWho=android:fragment:0 mBackStackNesting=1
    mAdded=true mRemoving=false mResumed=true mFromLayout=false mInLayout=false
    mHidden=false mDetached=false mRetainInstance=false mRetaining=false mHasMenu=false
    mFragmentManager=FragmentManager{4087d668 in ListViewFragmentsActivity{4087d588}}
    mImmediateActivity=my.app.ListViewFragmentsActivity@4087d588
    mActivity=my.app.ListViewFragmentsActivity@4087d588
    mNextAnim=17498112
    mContainer=android.widget.RelativeLayout@408876d8
    mView=android.widget.FrameLayout@40888a70
Added Fragments:
  #0: SimpleFragment{408883b0 #0 id=0x7f050000 simple}
Back Stack:
  #0: android.app.BackStackRecord@408884b8
    mName=simple mIndex=0 mCommitted=true
    mEnterAnim=#10b0000 mExitAnim=#10b0001
    Operations:
      Op #0:
        cmd=1 fragment=SimpleFragment{408883b0 #0 id=0x7f050000 simple}
    enterAnim=17498112 exitAnim=17498113
    popEnterAnim=17498112 popExitAnim=17498113
Back Stack Indices:
  #0: android.app.BackStackRecord@408884b8
FragmentManager misc state:
  mCurState=5 mStateSaved=false mDestroyed=false

FragmentManager dump (after rotation):

Active Fragments in 40877f38:
  #0: SimpleFragment{40878858 #0 id=0x7f050000 simple}
    mFragmentId=#7f050000 mContainerId#=7f050000 mTag=simple
    mState=4 mIndex=0 mWho=android:fragment:0 mBackStackNesting=1
    mAdded=true mRemoving=false mResumed=true mFromLayout=false mInLayout=false
    mHidden=false mDetached=false mRetainInstance=false mRetaining=false mHasMenu=false
    mFragmentManager=FragmentManager{40877f38 in ListViewFragmentsActivity{40877e58}}
    mImmediateActivity=my.app.ListViewFragmentsActivity@40877e58
    mActivity=my.app.ListViewFragmentsActivity@40877e58
    mContainer=android.widget.RelativeLayout@4087ed50
    mView=android.widget.FrameLayout@4087fc00
Added Fragments:
  #0: SimpleFragment{40878858 #0 id=0x7f050000 simple}
Back Stack:
  #0: android.app.BackStackRecord@40878a78
    mName=simple mIndex=0 mCommitted=false
    Operations:
      Op #0:
        cmd=1 fragment=SimpleFragment{40878858 #0 id=0x7f050000 simple}
Back Stack Indices:
  #0: android.app.BackStackRecord@40878a78
FragmentManager misc state:
  mCurState=5 mStateSaved=false mDestroyed=false
like image 441
Max Avatar asked Jan 12 '12 15:01

Max


3 Answers

As a workaround for this you can use onCreateAnimator/onCreateAnimation methods in your fragments.

For example for native fragments implementation:

@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
    if (enter) {
        return AnimatorInflater.loadAnimator(getActivity(), R.animator.slide_in_top);
    } else {
        return AnimatorInflater.loadAnimator(getActivity(), R.animator.fade_out);
    }
}

The same technique for support library fragments with Animation instead. In this case you also have more control over how would you like to play animation depending upon fragment state and/or arguments.

like image 156
q1p Avatar answered Nov 20 '22 19:11

q1p


Okay so this is a bug which also is a problem for native library (not only support library).

The only workaround I can suggest is to create your own back stack and then handle onBack with your own custom implementation setting the right animation as you go back through your own stack.

like image 34
Warpzit Avatar answered Nov 20 '22 19:11

Warpzit


An alternative suggestion to work around this issue is to download the source for the support library and make the change I suggested in the defect (http://code.google.com/p/android/issues/detail?id=25994) yourself, of course this means maintaining a copy of the support library yourself and not being able to use the native support, however that depends on how important this issue is for you.

like image 1
Wesio Avatar answered Nov 20 '22 19:11

Wesio