2012-04-04 13 views
0

Ich benutze einen ViewPager mit 4 Seiten, und ich bin auf der Suche nach einer effizienten Möglichkeit zum Ersetzen/Wechseln zwischen Fragmenten auf jeder Seite.Ersetze ein Fragment in einem ViewPager mit FragmentPagerAdapter

Dies ist das Interaktionsmuster, die ich versuche zu erstellen:

  1. Benutzer drückt auf einer Seite eine Schaltfläche, die zur Zeit Fragment A
  2. Fragment A hält, ist für einige neue Fragment B ausgelagert
  3. der Benutzer hat einige Arbeit in Fragment B, und dann drückt einen Knopf, wenn er/sie
  4. Fragment B gemacht wird entfernt, und wird von Fragment A (das Original-Fragment)
ersetzt

Ich habe einen Weg gefunden, dies zu tun, aber es scheint erhebliche Fehler zu haben. Die Lösung besteht darin, das ursprüngliche Fragment zu entfernen, und dann Überschreiben getItemPosition (im wesentlichen der Methode in diesen related question beschrieben):

//An array to keep track of the currently visible fragment in each page 
private final Fragment[] activeFragments= new Fragment[4]; 

public void openFragmentB(ViewPager pager, int position) { 

    startUpdate(pager); 

    //Remove the original fragment 
    FragmentTransaction transaction = fragmentManager.beginTransaction(); 
    transaction.remove(activeFragments[position]); 
    transaction.commit(); 

    //Create a new tile search fragment to replace the original fragment 
    activeFragments[position] = FragmentB.newInstance(); 
    pageStates[position] = PageState.STATE_B; 

    finishUpdate(pager); 
    notifyDataSetChanged(); 
} 

@Override 
public int getItemPosition(Object object) { 

    //If the main fragment is not active, return POSITION_NONE 
    if(object instanceof FragmentA) { 
     FragmentA a = (FragmentA) object; 
     if(pageStates[a.getPosition()] != PageState.STATE_A) { 
      return POSITION_NONE; 
     } 
    } 

    //If the secondary fragment is not active, return POSITION_NONE 
    if(object instanceof FragmentB) { 
     FragmentB b = (FragmentB) object; 
     if(pageStates[b.getPosition()] != PageState.STATE_B) { 
      return POSITION_NONE; 
     } 
    } 

    return POSITION_UNCHANGED; 
} 

Diese Methode funktioniert, aber unerwünschte Nebenwirkungen hat. Wenn das Fragment entfernt und seine Position auf POSITION_NONE festgelegt wird, wird das Fragment zerstört. Wenn der Benutzer also mit der Verwendung von FragmentB fertig ist, muss ich eine neue Instanz von FragmentA erstellen, anstatt das ursprüngliche Fragment erneut zu verwenden. Die Hauptfragmente im Pager (FragmentA in diesem Beispiel) enthalten relativ große datenbankgestützte Listen, daher möchte ich sie, wenn möglich, nicht neu erstellen.

Im Wesentlichen möchte ich nur Referenzen zu meinen 4 Hauptfragmenten behalten und sie in Seiten um- und auslagern, ohne sie jedes Mal neu erstellen zu müssen. Irgendwelche Ideen?

+0

'Fragmente' sind auch 'Ansichten', Sie könnten ein Layout mit den' Fragmenten' erstellen, die Sie austauschen müssen, dann verwenden Sie 'setVisibility()', um sie zu entfernen und hinzuzufügen. – adneal

Antwort

1

Eine einfache Möglichkeit, das erneute Erstellen Ihrer Fragmente zu vermeiden, besteht darin, sie als Mitgliedsvariablen in Ihrer Aktivität zu behalten. Ich mache das trotzdem in Verbindung mit onRetainCustomNonConfigurationInstance() um meine Fragmente während Konfigurationsänderungen zu behalten (meistens Bildschirmdrehung). Ich behalte meine Fragmente in einem Retainer-Objekt, da onRetainCustomNonConfigurationInstance nur ein einzelnes Objekt zurückgibt.

In Ihrem Fall, anstatt Fragment.newInstance() die ganze Zeit aufzurufen, überprüfen Sie einfach, ob die im Halteobjekt enthaltenen Fragmente null sind, bevor Sie ein neues erstellen. Wenn es nicht null ist, verwenden Sie einfach die vorherige Instanz erneut. Diese Überprüfung sollte in der Methode getItem (int) des ViewPager-Adapters erfolgen.

Eigentlich bedeutet dies, dass Sie behandeln, ob Fragmente wiederverwendet werden, wenn getItem aufgerufen wird, und überschreiben, ob die Methode getItemPosition (Object) immer POSITION_NONE für relevante Segmente zurückgibt.

1

FragmentPagerAdapter bietet eine überschreibbare Methode namens getItemId, die Ihnen hier helfen wird.

Wenn Sie jedem Fragment in Ihrer Sammlung einen eindeutigen langen Wert zuweisen und den Wert in dieser Methode zurückgeben, wird der ViewPager gezwungen, eine Seite neu zu laden, wenn er feststellt, dass sich die ID geändert hat.

Besser spät als nie, ich hoffe, das hilft jemand da draußen!

Verwandte Themen