14

Ich verwende ActionBarActivity, um 5 Registerkarten zu erstellen. Ich habe ViewPager verwendet, um zwischen den 5 Tabs mit SectionsPagerAdapter zu wischen, der FragmentPagerAdapter erweitert. Jede Registerkarte enthält ein Fragment mit einer Asyntask, die in der oncreateview-Methode aufgerufen wird. Wenn ich in einem Fragment bin, wird asynctask in einem anderen Fragment aufgerufen.Wie wird AsyncTask in ActionBarActivity-Fragmenten behandelt, wenn ViewPager verwendet wird?

Ich versuchte mit toast Nachrichten in oncreateview Methode ist jedes Fragment anstelle von asynctask. Aber falsche Toastnachrichten werden im falschen Fragment abgefeuert.

onCreate Methodencode:

 mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 


     mViewPager = (ViewPager) findViewById(R.id.pager_exp); 
     mViewPager.setAdapter(mSectionsPagerAdapter); 


     mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 
        @Override 
        public void onPageSelected(int position) 
        { 
         actionBar.setSelectedNavigationItem(position); 
         actionBar.setTitle(getHomePageTitle(position)); 
        } 
       }); 


     for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) 
     { 
      // Create a tab with text corresponding to the page title defined by 
      // the adapter. Also specify this Activity object, which implements 
      // the TabListener interface, as the callback (listener) for when 
      // this tab is selected. 
      actionBar.addTab(actionBar.newTab() 
        .setIcon(getPagedrawable(i)) 
        .setTabListener(this)); 

     } 

// Adapter Klassencode:

public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    public SectionsPagerAdapter(FragmentManager fm) 
    { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 


    switch (position) 
    { 
     case 0: 
      Fragment1 f1 = new Fragment1(); 
      return f1; 

     case 1: 
      Fragment2 f2 = new Fragment2(); 
      return f2; 

     case 2: 
      Fragment3 f3 = new Fragment3(); 
      return f3; 

     case 3: 
      Fragment4 f4 = new Fragment4(); 
      return f4; 


     case 4: 
      Fragment5 f5 = new Fragment5(); 
      return f5; 

     } 

     return null; 

    } 

    @Override 
    public int getCount() { 
     // Show 5 total pages. 
     return 5; 
    } 


} 

Fragemnt Klassencode:

public class F1 extends Fragment 
{ 
@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 

} 

@SuppressLint("NewApi") 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
{ 
    View view  = inflater.inflate(R.layout.f1,container, false); 

    Toast.makeText(getActivity(), "F1", Toast.LENGTH_SHORT).show(); 
    return view; 
} 
} 

Antwort

12

Die FragmentPagerAdapter hält zusätzliche Fragmente, neben dem einen, im wiederaufgenommenen Zustand. Die Lösung besteht darin, eine benutzerdefinierte OnPageChangeListener zu implementieren und eine neue Methode zu erstellen, wenn das Fragment angezeigt wird.

1) Erstellen LifecycleManager Schnittstelle Die Schnittstelle wird zwei Methoden haben und jedes ViewPager’s Fragment wird es implementieren. Diese Methoden sind wie folgt:

public interface FragmentLifecycle { 

    public void onPauseFragment(); 
    public void onResumeFragment(); 

} 

2) Lassen Sie jede Fragment implementieren die Schnittstelle hinzufügen iplements Anweisung für jede Klassendeklaration:

public class FragmentBlue extends Fragment implements FragmentLifecycle 
public class FragmentGreen extends Fragment implements FragmentLifecycle 
public class FragmentPink extends Fragment implements FragmentLifecycle 

3) Implementieren Interface-Methoden in jedem Fragment Um zu überprüfen, dass es wirklich wie erwartet funktioniert, werde ich nur den Methodenaufruf protokollieren und Toast anzeigen:

4) Anruf Interface-Methoden auf ViewPager Seitenwechsel Sie auf ViewPager gesetzt OnPageChangeListener und erhalten jedes Mal Rückruf bei ViewPager einer anderen Seite zeigt:

pager.setOnPageChangeListener(pageChangeListener); 

5) Implementieren OnPageChangeListener Ihre benutzerdefinierten Lifecycle Methoden

Zuhörer zu nennen wissen die neue Position und kann die Interface-Methode auf neues Fragment mit Hilfe von PagerAdapter aufrufen. Ich kann hier onResumeFragment() für das neue Fragment und onPauseFragment() für das aktuelle Fragment aufrufen.

Ich brauche auch Position ist das aktuellen Fragment zu speichern (zunächst die aktuelle Position gleich 0 ist), da ich nicht weiß, ob der Benutzer von links nach rechts gescrollt oder von rechts nach links. Sehen Sie, was ich in Code bedeute:

private OnPageChangeListener pageChangeListener = new OnPageChangeListener() { 

    int currentPosition = 0; 

    @Override 
    public void onPageSelected(int newPosition) { 

     FragmentLifecycle fragmentToShow = (FragmentLifecycle)pageAdapter.getItem(newPosition); 
     fragmentToShow.onResumeFragment(); 

     FragmentLifecycle fragmentToHide = (FragmentLifecycle)pageAdapter.getItem(currentPosition); 
     fragmentToHide.onPauseFragment(); 

     currentPosition = newPosition; 
    } 

    @Override 
    public void onPageScrolled(int arg0, float arg1, int arg2) { } 

    public void onPageScrollStateChanged(int arg0) { } 
}; 

Ich habe den Code nicht geschrieben.Vollständiges Tutorial hier: http://looksok.wordpress.com/2013/11/02/viewpager-with-detailed-fragment-lifecycle-onresumefragment-including-source-code/

+1

Danke dude..dies hat funktioniert – Anirudh

+0

@SomeoneSomewhere die benachbarten Fragmente müssen fortgesetzt werden, damit Sie zwischen ihnen scrollen können. – LordRaydenMK

+1

Ich habe es herausgefunden - der Adapter ist wirklich wichtig: Er muss alle Fragmente instanziieren und einen Verweis darauf behalten. getItem() gibt dann einfach das Objekt zurück. Leider hatte ich mit getItem() jedes Mal ein neues Fragment1, Fragment2, etc. erstellt. Dennoch ist die Verwendung von Fragmenten in einem ViewPager komplizierter - lächerlich. Die aktuelle Implementierung funktioniert wirklich nur für ein paar Fragmente, ansonsten wird die Heap-Nutzung schnell aufgebläht. –

1

verwenden

viewPager.setOffscreenPageLimit(1); // the number of pages you want to load in background 

und auch eine ProgressDialogue.

+0

Dies löst nicht mein Problem – Anirudh

+0

das ist keine brauchbare Antwort –

1

ViewPager erstellt Ansichten für Fragmente neben Ihrer aktuellen Seite. Dadurch haben Sie auch die Möglichkeit, alle für die benachbarten Fragmente erforderlichen Daten zu laden. Wenn Sie AsyncTasks zum Laden von Daten verwenden, führt die Verwendung dieser Funktion zu einer besseren Benutzererfahrung. Wenn Sie jedoch ein Ereignis benötigen, wenn eine bestimmte Seite vom Viewpager geöffnet wird, funktioniert die Lösung von LordRaydenMK.

Siehe mein Beitrag in folgendem Beitrag für die Verwendung von AsyncTasks in einem ViewPager:

AsyncTask runs on each page of the ViewPager

1

Hallo Sie mithilfe von Tag jedes Fragments und Call-Methode jedes Fragments auf Seite

Changed versuchen
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 
        @Override 
        public void onPageSelected(int position) { 
         actionBar.setSelectedNavigationItem(position); 
         actionBar.setTitle(getHomePageTitle(position)); 
         Fragment f = getFragrmentManager().findFragmentByTag(
           "" + position); 
         if (f != null) 
          f.refresh(); 
        } 
       }); 

und auf

  @Override 
     public Fragment getItem(int position) { 
      Fragment f=null; 

     switch (position) 
     { 
      case 0: 
       f = new Fragment1(); 
       break; 

      case 1: 
       f = new Fragment2(); 
       break; 

      case 2: 
       f = new Fragment3(); 
       break; 

      case 3: 
       f = new Fragment4(); 
       break; 


      case 4: 
       f = new Fragment5(); 
       break; 

      } 
      f.setTag(""+position); 
      return f; 

     } 
Verwandte Themen