2012-06-20 12 views
38

Ich möchte die Sichtbarkeit einer Schaltfläche festlegen, nachdem die Animation beendet ist.Ausführen der Aktion nach der Fragmenttransaktionsanimation

Das ist, was die Animation ruft:

android.support.v4.app.FragmentTransaction fAnimation = this.getActivity().getSupportFragmentManager().beginTransaction(); 
fAnimation.setCustomAnimations(android.R.anim.slide_in_left, R.anim.pull_out_to_left); 
if (this.isVisible()) { 
    fAnimation.hide(this); 
    fAnimation.commit(); 
} 

// code that will be executed when the fragment is gone (after the animation is over) 

Gibt es eine Möglichkeit, einen Hörer anzubringen zu wissen, wann mein Fragment ist weg?

Antwort

13

Sie müssen die Unterklasse Fragment erstellen und onCreateAnimator überschreiben, dann können Sie diese Animationen aus XML laden und Listener an sie anhängen.

z.

public class MyFragment extends Fragment 
{ 
    @Override 
    public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) 
    { 
     final int animatorId = (enter) ? R.anim.in_anim : R.anim.out_anim; 
     final Animator anim = AnimatorInflater.loadAnimator(getActivity(), animatorId); 
     anim.addListener(new AnimatorListenerAdapter() 
     { 
      @Override 
      public void onAnimationStart(Animator animation) 
      { 
       ... 
      } 

      @Override 
      public void onAnimationEnd(Animator animation) 
      { 
       ... 
      } 
     }); 

     return anim; 
    }  
+0

Ich versuchte dies, aber 'onCreateAnimation' wird nie aufgerufen. Ich benutze 'Fragment' aus dem Support-Paket v4 und es hat nicht' onCreateAnimatior', nur 'onCreateAnimation'. Gibt es einen Unterschied? – ffleandro

+0

Das ist mir vorher nicht aufgefallen, aber ich denke, Animatoren sind nur 3.0+. Richten Sie die Fragmenttransaktion korrekt ein, wie in http://stackoverflow.com/questions/4817900/android-fragments-and-animation gezeigt? – nmw

+0

ja, 'FragmentManager fragmentManager = getActivity(). GetSupportFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); ft.setCustomAnimations (R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right); ft.addToBackStack (null); ft.replace (R.id.tabContainer, Fragment); ft.commit(); fragmentManager.executePendingTransactions(); ' – ffleandro

51

Die Animator, die Geräte in seiner Antwort @nmw wurden in API Stufe 11 hinzugefügt und werden nicht mit Fragmenten arbeiten, wie durch die Android Support-Bibliothek implementiert.

zu Fragmente Animation Ereignissen hören zu können, erweiterte ich die Fragment Klasse Support-Bibliothek und overrode onCreateAnimation, einen benutzerdefinierten AnimationListener zu dem zurückAnimationsObjekt Befestigung:

public class MyFragment extends android.support.v4.app.Fragment { 

    private static final String TAG = "MyFragment"; 

    @Override 
    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { 

     Animation anim = AnimationUtils.loadAnimation(getActivity(), nextAnim); 

     anim.setAnimationListener(new AnimationListener() { 

      @Override 
      public void onAnimationStart(Animation animation) { 
       Log.d(TAG, "Animation started."); 
       // additional functionality 
      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { 
       Log.d(TAG, "Animation repeating."); 
       // additional functionality 
      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       Log.d(TAG, "Animation ended."); 
       // additional functionality 
      } 
     }); 

     return anim; 
    } 
} 
+8

Der Listener wird nicht aufgerufen, wenn enter den Wert false hat, da FragmentManagerImpl seinen eigenen Listener setzt. Die Rückgabe mit einem AnimationSet funktioniert. – sergio91pt

+0

@ sergio91pt Könnten Sie bitte erklären, wie? –

+7

@Sheikh Aman Erstellen Sie einfach einen neuen AnimationSet, fügen Sie die Animation (was Ihre Zuhörer hat gefassten) und der Satz zurück. Dies erlaubt FragmentManagerImpl einfach einen anderen Listener zu setzen, ohne den eigenen zu überschreiben. – sergio91pt

6

die Antworten hier oben zu verbinden, ist eine Probe ich verwende erfolgreich mit den Support-Bibliothek Fragmenten.

Erweitern Sie einfach das MenuFragment und legen Sie den Listener fest, um einen Rückruf zu erhalten, was danach ausgeführt werden soll.

public class MenuFragment extends Fragment { 

private WeakReference<OnMenuClosedListener> onMenuClosedListener; 

@Override 
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { 
    Animation anim = null; 
    if (enter) { 
     anim = AnimationUtils.loadAnimation(getActivity(), R.anim.anim_slide_in_top); 
    } else { 
     anim = AnimationUtils.loadAnimation(getActivity(), R.anim.anim_menu_slide_out_top); 
     anim.setAnimationListener(new AnimationListener() { 
      @Override public void onAnimationStart(Animation animation) { 
      } 
      @Override public void onAnimationRepeat(Animation animation) { 
      } 
      @Override public void onAnimationEnd(Animation animation) { 
       onMenuClosed(); 
      } 
     }); 
    } 

    // NOTE: the animation must be added to an animation set in order for the listener 
    // to work on the exit animation 
    AnimationSet animSet = new AnimationSet(true); 
    animSet.addAnimation(anim); 

    return animSet; 
} 

private void onMenuClosed() { 
    if (this.onMenuClosedListener != null) { 
     OnMenuClosedListener listener = this.onMenuClosedListener.get(); 
     if (listener != null) { 
      listener.onMenuClosed(); 
     } 
    } 
} 

public void setOnMenuClosedListener(OnMenuClosedListener listener) { 
    this.onMenuClosedListener = new WeakReference<MenuFragment.OnMenuClosedListener>(listener); 
} 

/** 
* Callback for when the menu is closed. 
*/ 
public static interface OnMenuClosedListener { 

    public abstract void onMenuClosed(); 

} 

}

+0

ich habe versucht, um die Animation zu einem 'AnimationSet' Zugabe, aber keiner der onAnimation Rückrufe erhalten beim Verlassen genannt. – toobsco42

+0

Arbeitete für mich, nur AnimationSet hinzufügen – Santacrab

0

Ich hatte dies in Xamarin zu tun. Meine Situation war, dass ich einen Rückruf brauchte, sobald die Fragmentanimation beendet war. Hier ist, wie ich gemacht, ohne es zu arbeiten, um irgendwelche flackern (dies ist C#/Xamarin):

public override Animation OnCreateAnimation(int transit, bool enter, int nextAnim) 
    { 
     Animation anim = base.OnCreateAnimation(transit, enter, nextAnim); 

     if (anim == null && nextAnim != 0) { 
      anim = AnimationUtils.LoadAnimation(Activity, nextAnim); 
     } 

     anim.SetAnimationListener(this); 
     return anim; 
    } 

    public void OnAnimationEnd(Animation animation) 
    { 
    } 

    public void OnAnimationRepeat(Animation animation) 
    { 
    } 

    public void OnAnimationStart(Animation animation) 
    { 
    } 

Hinweis:

  • Das Elternfragment hat zu implementieren Animation.IAnimationListener
  • Sie haben eine AnimationSet sonst zurück Die FragmentManager überschreibt Ihren Listener und die Callbacks werden nicht ausgelöst.