1

Ich versuche, Fragmente in ViewPager zu ersetzen, aber ich stehe vor einem Problem, das ich seit mehreren Tagen nicht beheben konnte. Der entsprechende Code und spezifisches Problem, wie ich es verstehe, sind nachfolgend beschrieben:ViewPager aktualisiert keine Fragmente

public class ViewPageAdapter extends FragmentStatePagerAdapter { 
int mNumOfTabs; 
FragmentManager mFragmentManager; 
Fragment0 currentFragment0; 
Fragment1 currentFragment1; 
Fragment2 currentFragment2; 
boolean getItemNeverCalled = true; 

public ViewPageAdapter(FragmentManager fm, int numOfTabs){ 
    super(fm); 
    mFragmentManager = fm; 
    this.mNumOfTabs = numOfTabs; 
} 

@Override 
public Fragment getItem(int position){ 
    switch (position){ 
     case 0: 
      if(currentFragment0 == null){ 
       Fragment0 tab0 = new Fragment0(); 
       currentFragment0 = tab0; 
       return currentFragment0; 

      } 
      else { 
       mFragmentManager.beginTransaction().remove(currentFragment0).commit(); 
       int value = selectedPlant.getMoistureFrag().getStat().getOptimalLevel(); 
       currentFragment0 = Fragment0.newInstance(key0, value); 
       notifyDataSetChanged(); // calls getItem(0). 

       return currentFragment0; 
      } 
     case 1: 
      if(currentFragment1 == null){ 
       LightFragment tab1 = new Fragment1(); 
       currentFragment1 = tab1; 

       return currentFragment1; 
      } 
      else { 
       mFragmentManager.beginTransaction().remove(currentFragment1).commit(); 
       int value = selectedPlant.getLightFrag().getStat().getOptimalLevel(); 
       currentFragment1 = currentFragment1.newInstance(key1, value); 
       notifyDataSetChanged(); 

       return currentFragment1; 
      } 
     case 2: 
      if(currentFragment2 == null){ 
       Fragment2 tab2 = new Fragment2(); 
       currentFragment2 = tab2; 

       return currentFragment2; 
      } 
      else { 
       mFragmentManager.beginTransaction().remove(currentFragment2).commit(); 
       int value = selectedPlant.getTempFrag().getStat().getOptimalLevel(); 
       currentFragment2 = Fragment2.newInstance(key2, value); 
       notifyDataSetChanged(); 

       return currentFragment2; 
      } 

     default: 
      return null; 
    } 
} 



@Override 
public int getCount(){ 
    return mNumOfTabs; 
} 

@Override 
public int getItemPosition(Object object){ 
      return POSITION_NONE; 
} 

Ich habe die getItemPosition(Object object) Methode außer Kraft gesetzt, um immer POSITION_NONE zurückzukehren, und notifyDataSetChanged() bei Bedarf (glaube ich) genannt. Was passiert ist, dass notifyDataSetChanged()getItem(0) aufruft, die `notifyDataSethanged() ... und so weiter aufruft. Das verursacht eine TransactionTooLargeException und stürzt die App ab.

Nur um einige Hintergrundinformationen zu den if/else Aussagen in jedem Fall zu geben: die if soll ein leeres Moisture/Light/etc Fragment auf den Bildschirm laden. Dies soll beim Start geschehen. Die Anweisung else wird ausgeführt, wenn ein Benutzer auf ein Element in der Navigationsleiste drückt, das einige Daten enthält. Diese Daten werden dann extrahiert und als Argumente für die Fragmente gesetzt, die das ursprüngliche leere Fragment ersetzen sollen.

Ich schätze wirklich jede Hilfe. Dieses Problem macht mich verrückt.

Antwort

1

Warum in der Welt sind Sie Fragmente neu erstellen, wenn Sie nur die alten aktualisieren können?
Wenn Sie notifyDataSetChanged während getItem aufrufen, erzwingen Sie einen neuen Aufruf von getItem, der einen neuen Aufruf erzwingt ... also erstellen Sie tatsächlich einen zirkulären Aufruf!
Da Sie immer die gleiche Fragmentklasse in jeder Position behalten und Sie an dem Fragment festhalten, sollten Sie das Fragment nicht ersetzen. Ändern Sie einfach das Fragment, das Sie halten, um die neuen Werte anzuzeigen. Der Code, den Sie verwenden, wird nur benötigt, wenn Sie verschiedene Fragmentklassen für die Position ändern möchten.

+0

Hatte anfangs einige Probleme (bevor ich wusste, dass diese Methode existierte), so folgte ich http://StackOverflow.com/Questions/7723964/Replace-Fragment-Inside-AviewPager und mehrere andere Beiträge, die das gleiche vorschlugen . Ich werde dich wissen lassen, wie es läuft. –

+0

BTW, da Sie immer die gleiche Fragmentklasse in jeder Position behalten und Sie an dem Fragment festhalten, sollten Sie Ihren Code neu gestalten. Sie sollten das Fragment nicht ersetzen, ändern Sie einfach das Fragment, das Sie halten, um die neuen Werte anzuzeigen. Der Code, den Sie verwenden, wird nur benötigt, wenn Sie verschiedene Fragmentklassen für die Position ändern möchten. – lionscribe

+0

Ok, ich verstehe. Bedeutet das, dass ich die getItem-Methode nach der Initialisierung der Registerkarten beim Start nicht verwenden sollte? –

Verwandte Themen