2016-06-27 3 views
0

Ich habe eine ViewPager, FragmentPagerAdapter und ein paar Fragmente. Ich muss das Fragment benachrichtigen, wenn der Benutzer zu einem anderen wechselt (damit der erste seine Arbeit abschließen kann). Ich schaue in ViewPager.OnPageChangeListener, aber sehe keine Möglichkeit, die aktuelle Fragment-Instanz zu erhalten, wenn die Änderung auftritt. Auch ViewPager.getCurrentItem() gibt die neue Position zurück, wenn OnPageChangeListener.onPageSelected aufgerufen wird.ViewPager und FragmentPagerAdapter: Wie benachrichtigt man die Fragment-Instanz, dass sie auf ein anderes Fragment umgestellt wird?

Ist garantiert, dass Fragment.onPause() für das vorherige Fragment jedes Mal aufgerufen wird, wenn ein neues ausgewählt wird? Das würde die Dinge sicherlich vereinfachen.

Antwort

0

Sie können einen Verweis auf Ihr Fragment auf Klassenebene beibehalten, z. B. mCustomFragment. Dann innerhalb Ihrer Fragment-Setup eine öffentliche Methode, die die Arbeit abgeschlossen wird, rufen Sie einfach diese Methode, wenn Sie es in der ViewPager.OnPageChangeListener benötigen.

+0

Nein, ich sehe nicht, wie es funktioniert. Nehmen wir an, ich speichere den Verweis auf das aktuelle Fragment in 'FragmentPagerAdapter.getItem', aber zu dem Zeitpunkt, zu dem' OnPageChangeListener.onPageSelected' aufgerufen wird, ist es bereits zu spät. Ich weiß, auf welches Fragment ich ** ** umstelle, aber nicht was ** von **. –

+0

Und ich glaube nicht, dass 'getItem' jedes Mal aufgerufen wird, wenn ein Übergang auftritt. Es könnte intern zwischengespeichert werden. –

+0

Ok ich sehe deinen Standpunkt. Keine Notwendigkeit, es von getItem() zu bekommen. Wie wäre es mit der Verfolgung Ihrer aktuellen Viewpager-Seite? Sie können alles verwenden, einen Index, eine Zeichenfolge. Dann erhalten Sie bei onPageSelected Ihre Referenz basierend auf dem Objekt, auf dem Sie die letzte Seitenreferenz speichern, und rufen Sie schließlich eine Methode auf. – Matteo

0

Vielleicht fügen Sie eine Art von Gesten Listener an, um zu bestimmen, in welcher Weise der Swipe auftritt. Bestimmen Sie dann auf OnPageChangeListener basierend auf der letzten vor dem Aufruf verwendeten Geste, ob +1 oder -1 auf den aktuellen Viewpager-Index gesetzt werden soll.

+0

Das löst nicht das Problem, das Fragment _instance_ zu erhalten. –

+0

Ok, warum nicht eine benutzerdefinierte Adapter-Klasse, und erstellen Sie eine Methode, die ein Fragment basierend auf dem Index-Pass in es zurückgibt? Ich glaube, ich verstehe die Frage nicht ganz. – CodeCody

1

Gemäß der Dokumentation scheint onPause ruft, wenn jemals Benutzer das Fragment verlassen (obwohl es nicht immer bedeutet, das Fragment wird zerstört).

https://developer.android.com/guide/components/fragments.html

+0

Offensichtlich nicht, ich habe dort einen Haltepunkt gesetzt und es wird nicht getroffen, wenn ich zwischen zwei Fragmenten hin und her gehe. –

+0

können Sie Ihren FragmentPagerAdapter Code einfügen –

+0

https://gist.github.com/VioletGiraffe/99b8362e7dbfdfc2fb1309d28874725b –

0

Hier ist meine Lösung, die tatsächlich funktioniert. Es beinhaltet Sendungen zur Benachrichtigung der Fragmente.

Zuerst habe ich erweitert die Fragment Klasse:

@SuppressLint("ValidFragment") 
public class ExtendedFragment extends Fragment { 

    public static final String FragmentIdTag = "Fragment ID"; 
    public static final String FragmentSwitchedEventId = "FragmentSwitchedEvent"; 

    @SuppressLint("ValidFragment") 
    protected ExtendedFragment(FragmentType fragmentId) { 
     m_fragmentType = fragmentId; 
    } 

    public void onSwitchedAway() { 
    } 

    public BroadcastReceiver broadcastReceiver() { 
     return m_receiver; 
    } 

    class Receiver extends BroadcastReceiver { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      FragmentType newFragmentType = (FragmentType) intent.getSerializableExtra(FragmentIdTag); 
      if (newFragmentType != m_fragmentType) 
       onSwitchedAway(); 
     } 
    } 

    protected final FragmentType m_fragmentType; 
    Receiver m_receiver = new Receiver(); 
} 

FragmentType ist enum, die für jedes Fragment anders. Alle Fragmente erstrecken sich ExtendedFragment (ein schrecklicher Name, ich weiß. Fühlen Sie sich frei, einen besseren vorzuschlagen) und passender einzigartiger FragmentType Wert zu seinem Erbauer.

Dann benutze ich die Viewpager.OnPageChangeListener das Fragment Schalter zu erkennen:

pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} 

      @Override 
      public void onPageSelected(int position) { 
       FragmentType newType = fragmentTypeForPosition(position); 
       Intent i = new Intent(ExtendedFragment.FragmentSwitchedEventId); 
       i.putExtra(ExtendedFragment.FragmentIdTag, newType); 
       LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(i); 
      } 

      @Override 
      public void onPageScrollStateChanged(int state) {} 
     }); 

Und schließlich, wenn die Fragmente Instanziieren vergessen sie nicht als Rundfunkempfänger zu registrieren:

pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

      @Override 
      public void onPageSelected(int position) { 
       FragmentType newType = fragmentTypeForPosition(position); 
       Intent i = new Intent(ExtendedFragment.FragmentSwitchedEventId); 
       i.putExtra(ExtendedFragment.FragmentIdTag, newType); 
       LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(i); 
      } 
     }); 

Erledigt. Jetzt können die Fragmente public void onSwitchedAway() überschreiben.

Verwandte Themen