2016-04-08 8 views
3

Das ist mein Szenario:Aktualisieren von Daten in ViewPager Fragment

I ViewPager in meiner Aktivität haben, die 6 Fragment beherbergt. Ich deaktiviert Paging, indem sie mit dem Finger wischen, so wann immer ich will klauen ich ähnliche Taste und:

viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true); 

In jedem Fragment, das geklaut wird (nach dem Streichen fertig ist) ich eine GET Anfrage senden möchte meine Server und holen Sie einige Daten und zeigen Sie es in diesem Fragment. dafür, dass:

erster Ansatz: habe ich diesen Code in meinen Fragmenten, die, sobald Fragment sichtbar läuft:

@Override 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
     super.setUserVisibleHint(isVisibleToUser); 
     if(isVisibleToUser) 
     { 
      sendGetRequest(); 
     } 
} 

Aber war hier ein Problem: dass setUserVisibleHint genau ausführt wenn das Fragment sichtbar war, und deshalb kam die Animation des Wischens mit etwas Verzögerung (es war nicht glatt genug).

So habe ich Zweiter Ansatz: Ich habe einen OnPageChangeListener() zu ViewPager in gehosteten Aktivität wie folgt aus:

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      int CurrentPossition = 0; 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } 
      @Override 
      public void onPageSelected(int position) { 
       CurrentPossition = position; 
      } 
      @Override 
      public void onPageScrollStateChanged(int state) { 
       if(state == ViewPager.SCROLL_STATE_IDLE && CurrentPossition != 0){ 
        Toast.makeText(getBaseContext(),"finished" , Toast.LENGTH_SHORT).show(); 

        try{ 
         new fragment_two().sendGetRequest();; 
        }catch(Exception ex){ 
         ex.printStackTrace(); 
        } 
       } 
      } 
     }); 

Es funktioniert großartig, und Toast zeigt, sobald Swipe abgeschlossen, aber im Gegensatz zu Fragment, das vollständig sichtbar ist, wenn sendGetRequest() läuft, bekomme ich NullPointerException. Stacktrace

hier:

04-08 20:15:37.840 12848-12848/com.example.mohamad.travelagency W/System.err: java.lang.NullPointerException 
04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:152) 
04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:103) 
04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:143) 
04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.app.AlertDialog.<init>(AlertDialog.java:98) 
04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.app.ProgressDialog.<init>(ProgressDialog.java:77) 
04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err:  at com.example.mohamad.travelagency.fragment_two.GetServetData_L1(fragment_two.java:458) 
04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err:  at com.example.mohamad.travelagency.MainActivity$1.onPageScrollStateChanged(MainActivity.java:124) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.support.v4.view.ViewPager.dispatchOnScrollStateChanged(ViewPager.java:1811) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.support.v4.view.ViewPager.setScrollState(ViewPager.java:404) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.support.v4.view.ViewPager.access$000(ViewPager.java:91) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.support.v4.view.ViewPager$3.run(ViewPager.java:250) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.view.Choreographer.doCallbacks(Choreographer.java:574) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.view.Choreographer.doFrame(Choreographer.java:543) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.os.Handler.handleCallback(Handler.java:733) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:95) 
04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.os.Looper.loop(Looper.java:136) 
04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:5271) 
04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err:  at java.lang.reflect.Method.invokeNative(Native Method) 
04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err:  at java.lang.reflect.Method.invoke(Method.java:515) 
04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err:  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:851) 
04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:667) 
04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err:  at dalvik.system.NativeStart.main(Native Method) 

eine Idee wäre toll. freundlichen Grüßen

Antwort: Daniel Nugents Code gut funktioniert hat, neben für ProgressDialog zeigt beim Senden GET Anfrage i verwendet:

final ProgressDialog dialog = new ProgressDialog(new MainActivity()); 

dieser Code zurückgegeben zu Nullpointer, entfernt ich es und jetzt gut arbeiten.

+0

Beitrag stacktrace – Naveed

+0

Fragment über getItem erhalten () in onpageSelected(), das zu Ihrem Viewpager-Adapter hinzugefügt wird. Überprüfen Sie null. Wenn nicht null, führe dann deinen Serveraufruf – Sayem

+0

aus, das Fragment wird vollständig sichtbar, wäre es möglich, dass das Nullfragment sichtbar wird und seine statischen Ansichten zeigt? –

Antwort

3

Die Verwendung der ViewPager.OnPageChangeListener ist der richtige Weg, aber Sie müssen Ihren Adapter ein wenig umgestalten, um einen Verweis auf jedes Fragment im FragmentPagerAdapter zu behalten.

Sie tun, dass die instantiateItem() Methodenüberschreibung in dem Adapter verwendet wird, hier ein vereinfachtes Beispiel ist:

class PagerAdapter extends FragmentPagerAdapter { 
     String tabTitles[] = new String[] { "One", "Two", "Three", "Four"}; 
     Context context; 

     //This will contain your Fragment references: 
     public Fragment[] fragments = new Fragment[tabTitles.length]; 

     public PagerAdapter(FragmentManager fm, Context context) { 
      super(fm); 
      this.context = context; 
     } 
     @Override 
     public int getCount() { 
      return tabTitles.length; 
     } 
     @Override 
     public Fragment getItem(int position) { 
      switch (position) { 
      case 0: 
       return new FragmentOne(); 
      case 1: 
       return new FragmentTwo(); 
      case 2: 
       return new FragmentThree(); 
      case 3: 
       return new FragmentFour(); 
      } 
      return null; 
     } 

     //This populates your Fragment reference array: 
     @Override 
     public Object instantiateItem(ViewGroup container, int position) { 
      Fragment createdFragment = (Fragment) super.instantiateItem(container, position); 
      fragments[position] = createdFragment; 
      return createdFragment; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      // Generate title based on item position 
      return tabTitles[position]; 
     }   
} 

Dann stattdessen ein neues Fragment erstellen, verwenden Sie die im Adapter enthalten:

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

    @Override 
    public void onPageSelected(int position) { 

     // do this instead, assuming your adapter reference 
     // is named mAdapter: 
     Fragment frag = mAdapter.fragments[position]; 
     if (frag != null && frag instanceof FragmentTwo) { 
      ((FragmentTwo)frag).sendGetRequest(); 
     } 
    } 

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

Hinweis: Wenn Sie in Ihrem Adapter verschiedene Fragmentklassen verwenden, können Sie eine Schnittstelle implementieren, die sendGetRequest() definiert, und in jeder Ihrer Fragmentklassen die sendGetRequest() -Methode implementieren.

Wenn Sie mit dem Interface-Ansatz nicht gehen, müssen Sie das Fragment zu Ihrer eigenen Fragmente Art werfen, wie im obigen Beispiel gezeigt, das heißt:

if (frag instanceof FragmentTwo) { 
    ((FragmentTwo)frag).sendGetRequest(); 
} 
+0

danke Daniel Nugent. für Ihre vollständige Antwort. Es gibt ein Problem:
'mAdapter.fragments [CurrentPossition];' returns ** Fragment **, aber mein Wunsch ist ein ** fragment_two **, das sich von Fragment erstreckt, Wie kann ich es in 'fragment_two' –

+0

wieder ich bin Wenn ich denselben Fehler erhalte, habe ich FragmentStatePagerAdapter verwendet, ich habe ihn in FragmentPagerAdapter geändert, aber wieder NullPoiterException. –

+1

Ihr Ansatz hat wirklich funktioniert, vielen Dank Kumpel. –

0

Rufen Sie die Methode sendGetRequest() im Listenpagerlistener nicht auf, sondern rufen Sie Ihre GET-Anforderung in der onCreateView-Methode in Ihrer fragment_two-Fragmentklasse auf. Der Grund dafür ist, dass Sie sicherstellen, dass alle Ihre Ansichten in fragment_two ordnungsgemäß über die Lebenszyklusereignisse des Fragments initialisiert wurden.

+0

wie ich im ersten ansatz erwähnt, funktionierte alles gut, wenn ich sendGetRequest() in onCreateView oder setUserVisibleHint verwendet, das Problem in diesem Fall ist Übergang war nicht glatt genug. Dieser Mangel an Sanftheit könnte daran liegen, dass ProgressDialog am Anfang der Anfrage angezeigt wird, aber es sollte angezeigt werden –

+0

Was ist der Grund für den Aufruf der GET-Anfrage richtig, wenn der Benutzer das Fragment sieht? Standardmäßig lädt der Ansichts-Pager das Fragment des aktuellen Fragments und das Fragment rechts des aktuellen Fragments vor. Für eine bessere Benutzererfahrung würde ich die Daten vorab laden, bevor der Benutzer das Fragment sieht, indem Sie die Methode in onCreateView einfügen, sodass Sie den Fortschrittsdialog nicht anzeigen müssen. –

Verwandte Themen