2012-01-12 19 views
27

sto inserendo frammenti in attività utilizzando questo codice:Frammento perso animazione della transizione dopo la modifica della configurazione

codice
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 è:

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

Quando ho pop il frammento da backstack tramite pulsante Indietro subito dopo il lancio, quindi tutto è a posto e posso vedere l'animazione in dissolvenza. Ma se ruoto il dispositivo e premi il pulsante Indietro, il frammento scompare senza animazione.

È un comportamento Android o sto facendo qualcosa di sbagliato?

MODIFICA: Sembra che dopo la rotazione FragmentManager non abbia ripristinato le animazioni (enterAnim, exitAnim, popEnterAnim e popExitAnim) per BackStackEntry.

discarica FragmentManager (senza rotazione):

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}} 
    [email protected] 
    [email protected] 
    mNextAnim=17498112 
    [email protected] 
    [email protected] 
Added Fragments: 
    #0: SimpleFragment{408883b0 #0 id=0x7f050000 simple} 
Back Stack: 
    #0: [email protected] 
    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: [email protected] 
FragmentManager misc state: 
    mCurState=5 mStateSaved=false mDestroyed=false 

discarica FragmentManager (dopo la rotazione):

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}} 
    [email protected] 
    [email protected] 
    [email protected] 
    [email protected] 
Added Fragments: 
    #0: SimpleFragment{40878858 #0 id=0x7f050000 simple} 
Back Stack: 
    #0: [email protected] 
    mName=simple mIndex=0 mCommitted=false 
    Operations: 
     Op #0: 
     cmd=1 fragment=SimpleFragment{40878858 #0 id=0x7f050000 simple} 
Back Stack Indices: 
    #0: [email protected] 
FragmentManager misc state: 
    mCurState=5 mStateSaved=false mDestroyed=false 
+0

Anche io sto avendo lo stesso problema. Hai avuto fortuna a capirlo? – khendricks

+0

@khendricks No e tu? – Max

+1

Sfortunatamente no. Sono scioccato dal fatto che non ci siano molte altre persone che si lamentano di questo. Ho creato una segnalazione di bug per questo problema. http://code.google.com/p/android/issues/detail?id=25994&can=4&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars – khendricks

risposta

2

Va bene così questo è un bug che è anche un problema per la libreria nativa (non solo il supporto biblioteca).

L'unica soluzione che posso suggerire è creare il proprio back stack e quindi gestire onBack con la propria implementazione personalizzata impostando l'animazione corretta mentre si torna indietro nel proprio stack.

1

Un suggerimento alternativo per ovviare a questo problema è scaricare il codice sorgente per la libreria di supporto e apportare la modifica suggerita nel difetto (http://code.google.com/p/android/issues/detail?id=25994), naturalmente questo significa mantenere una copia della libreria di supporto da soli e non essere in grado di utilizzare il supporto nativo, tuttavia ciò dipende dall'importanza del problema per te.

10

Per ovviare a questo problema è possibile utilizzare i metodi onCreateAnimator/onCreateAnimation nei propri frammenti.

Ad esempio di attuazione frammenti nativi:

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

La stessa tecnica di frammenti libreria di supporto con animazione invece. In questo caso hai anche più controllo su come ti piacerebbe giocare all'animazione a seconda dello stato e/o degli argomenti del frammento.

+0

Quando si utilizza il supporto-v4, è possibile utilizzare 'onCreateAnimation()' e la classe helper 'AnimationUtils' per il caricamento di animazioni. –

+1

Ricordare che questo meccanismo non affronta l'utilizzo di un'animazione diversa per lo schiocco dello schienale. Dovrai gestire questo flusso da solo. –

+0

Questo metodo interferirà con 'transaction.setCustomAnimations'? Può impostare l'animatore due volte. – Ryde

1

È possibile utilizzare onCreateAnimation più AnimationUtils per ogni frammento anziché transaction.setCustomAnimations (..). Anche per saltare l'animazione durante il ripristino, prendere in considerazione la bandiera boleiana.

@Override 
public void onCreate(@Nullable Bundle savedInstanceState) { 
    mIsRestoring = savedInstanceState != null; 
    ... 
} 

@Override 
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { 
    if (mIsRestoring) { 
     mIsRestoring = false; 
     return null; 
    } 
    if (enter) { 
     return AnimationUtils.loadAnimation(getContext(), R.anim.enter_from_right); 
    } else { 
     return AnimationUtils.loadAnimation(getContext(), R.anim.exit_to_left); 
    } 
} 
+0

ma come implementiamo l'animazione exit-to-right? Voglio dire, quando si fa la transazione frammento si passano 4 diverse animazioni. 2 per movimento in avanti, 2 per popbackstack. come enter-from-right/exit-to-left e enter-from-left/exit-to-right –

Problemi correlati