2013-04-18 11 views
42

Mój adapter pagera (rozszerza PagerAdepter) ma w sobie widok tekstowy. Aktualizuję ten tekst za pomocą opcji MainActivity on onPageSelected. Przegląd tekstu aktualizacji dla pozycji> 0, ale strona początkowa (pozycja 0) nie aktualizuje się przy starcie. Kiedy przesuwaj do przodu, przesuń w tył; ustawia wartość dla pozycji 0, ale nie mogę ustawić wartości ON START. Jak ustawić wartość strony głównej?onPageSelected nie działa na pierwszej stronie.

public void onPageSelected(int position) { 

      switch (position) { 
       case 0: 

        PagerAdapter.tv.setText("value"); // => doesnt work on start 

        break; 

          default: 
            PagerAdapter.tv.setText("value"); 
             break; 
} 
} 

Pełny Kod:

public class QuizStart extends SlidingFragmentActivity { 
@Override 
     protected void onCreate(final Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      this.setContentView(R.layout.activity_main); 

       mPager = (ViewPager)findViewById(R.id.pager);   
      QuestionPagerAdapter mAdapter = new QuestionPagerAdapter(); 

      mPager.setAdapter(mAdapter); 
      QuizStart.onPageSelected(0); 

     mPager.setOnPageChangeListener(new OnPageChangeListener() { 


      @Override 
      public void onPageScrollStateChanged(int arg0) { } 

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

      @Override 
      public void onPageSelected(int position) { 

      switch (position) { 
       case 0: 

        PagerAdapter.tv.setText("value"); // => doesnt work on start 

        break; 

          default: 
            PagerAdapter.tv.setText("value"); 
             break; 
       } 
      } 

     }); 
} 
} 
+0

Dlaczego wasz PageAdapter mają widok w nim? To na początek brzmi podejrzanie. Co próbujesz osiągnąć? – dmon

+0

Dostaję dane z bazy danych i ustawię je w widoku tekstowym paderadapters – metemet06

Odpowiedz

49

Można ręcznie wywołać onPageSelected(0) podczas tworzenia OnPageChangeListener ustawić stan początkowy:

OnPageChangeListener pageChangeListener = new OnPageChangeListener() { 
    @Override 
    public void onPageScrollStateChanged(int arg0) { } 

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

    @Override 
    public void onPageSelected(int position) { 

     switch (position) { 
     case 0: 
      QuizStart.next.setText(getmycurrentpage()+""); 
      break; 

     default: 

      QuizStart.next.setText(getmycurrentpage()+""); 
      break; 
     } 
    } 
}); 

    mPager.setOnPageChangeListener(pageChangeListener); 
    // do this in a runnable to make sure the viewPager's views are already instantiated before triggering the onPageSelected call 
    mPager.post(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      pageChangeListener .onPageSelected(viewPager.getCurrentItem()); 
     } 
    }); 

Edycja

Teraz będzie nie g et Null Pointer exception jak wskazał przez @ metemet06

+0

jak mogę z niego korzystać? Nie mogłem dowiedzieć się, – metemet06

+0

Zaraz po twoim 'viewPager.setAdapter (pagerAdapter)', zadzwoń 'pagerAdapter.onPageSelected (0)' – ianhanniballake

+0

Więc będę utworzyć metodę onPageSelected() w pagerAdapter? – metemet06

0

Wydaje mi się, że to, co naprawdę chcesz robić to nadrzędne getPageTitle(), a potem, gdzieś indziej, chwytając że tytuł strony i ustawienie go jako tekstu w TextView użytkownika.

W ten sposób, kiedy zainicjować swoją aktywność, zainicjować PagerAdapter i nazywają getTitle(0). Da ci to tytuł strony 0. Teraz ustaw to w widoku tekstowym aktywności. Później, gdy tylko zmienisz strony, po prostu zadzwoń pod numer getTitle(newPosition) i zaktualizuj ten TextView.

0

Prawdopodobnie używasz niektórych zadań AsyncTasks do załadowania zestawu danych i ciężko jest określić, które zadanie będzie ostatnim. I dopiero po tym ostatnim zadaniu, gdy cały zestaw danych zostanie ukończony, możesz zadzwonić do OnPageSelected, ponieważ wykonuje on kolor w interfejsie użytkownika w całym zestawie danych.

Zamiast nazywając OnPageSelected-funkcję ręcznie, gdy strona jest ładowana po raz pierwszy, raczej budować krok po kroku UI „normalne” -Way. Później, gdy użytkownik zmieni stronę, zestaw danych powinien być kompletny i jest zapisywany, aby umożliwić aktualizację w funkcji OnPageSelected.

0

Ponieważ zrobiłem to, co sugerowano tu i to nie działa będę pisać co nie działa dla mnie było dodanie funkcji instancji do onPageScrolled, tak:

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

      adapter.closeText(arg0, viewPager); 

    } 

Prawdopodobnie przyczyną tego, że pracował że onPagesScrolled jest aktywowany dalej w dół linii androida menedżera zadań, więc zapobiegamy niepożądanej sytuacji, w której strona jest zawyżona, pomijając załącznik do nasłuchujących do widoku.

1

Rozwiązałem problem w mojej aplikacji, dodając kod, który powinien zostać wykonany na pierwszej stronie metody onCreate() - mojej aktywności.

Nie jest to najładniejszy hack i wiąże się z nadmiarowym kodem, ale ponieważ chcę tylko załadować dane tekstowe podczas zmiany stron, jest to najprostszy sposób, aby to zrobić w moim przypadku.

Wywołanie onPageSelected() powodowane ręcznie NullPointerExceptions, tylko Das opisane w powyższych uwag.

3

Moim rozwiązaniem było rozszerzenie adaptera stronicowania i utworzenie w nim interfejsu. Następnie adapter powinien wywołać interfejs tylko raz po utworzeniu adaptera. Wewnątrz wywołania zwrotnego interfejsu można wywołać metodę onPageChanged bez zerowego punktu zerowego.Dodaj tę klasę do projektu i przedłużyć z niej swój adapter. Nie zapomnij ustawić detektora na adapterze przed ustawieniem adaptera na viewpager. Klasa adaptera poniżej:

public abstract class ExtendedPagerAdapter extends FragmentPagerAdapter { 

private boolean instantiated; 
private AdapterListener adapterListener; 

public interface AdapterListener { 
    void onAdapterInstantiated(); 
} 

public ExtendedPagerAdapter(FragmentManager fragmentManager) { 
    this(fragmentManager, null); 
} 

public ExtendedPagerAdapter(FragmentManager fragmentManager, AdapterListener adapterListener) { 
    super(fragmentManager); 
    this.adapterListener = adapterListener; 
    instantiated = false; 
} 

@Override 
public void finishUpdate(ViewGroup container) { 
    super.finishUpdate(container); 
    if (!instantiated) { 
     instantiated = true; 
     if (adapterListener != null) { 
      adapterListener.onAdapterInstantiated(); 
     } 
    } 
} 

public void setAdapterInstantiatedListener(AdapterListener adapterListener) { 
    this.adapterListener = adapterListener; 
} 
} 
+0

To niezły pomysł, w moim przypadku działa idealnie! Chcę poświęcić trochę więcej czasu na sprawdzenie, czy 'finishUpdate' jest wywoływane po dołączeniu fragmentu do działania. – Entreco

+0

Dzięki :) Według Google [FragmentPagerAdapter.finishUpdate] (https://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html#finishUpdate (android.view.ViewGroup)) jest wywoływane, gdy zmiana na wyświetlanych stronach została zakończona. Tak więc, za każdym razem, gdy fragment się zmienił, wywoływana jest aktualizacja końcowa. Również jeśli zanurkujemy w źródło, widzimy, że ta metoda zatwierdza i wykonuje wszystkie oczekujące transakcje :) –

+0

Zasługuje na więcej upvotes – deviant

0

Ten kod działa dla mnie. Najpierw zainicjuj program nasłuchujący pagekange. Po ustawieniu setCurrentItem.

viewPager.setAdapter(adapter); 
     viewPager.setOffscreenPageLimit(1); 

     final ViewPager.OnPageChangeListener listener = new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     } 

     @Override 
     public void onPageSelected(int position) { 

     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 
     } 
     }; 
     viewPager.addOnPageChangeListener(listener); 
     viewPager.setCurrentItem(position); 
25

Dla mnie działa następny kod

viewPager.addOnPageChangeListener(myOnPageChangeListener); 

.

ViewPager.OnPageChangeListener myOnPageChangeListener = new ViewPager.OnPageChangeListener() { 

    //declare key 
    Boolean first = true; 

    @Override 
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     if (first && positionOffset == 0 && positionOffsetPixels == 0){ 
      onPageSelected(0); 
      first = false; 
     } 
    } 

    @Override 
    public void onPageSelected(int position) { 
     //do what need 
    } 

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

To jest fajna sztuczka, która łatwo rozwiązuje problem. – GregM

0

Właściwie znalazłem dobry sposób na podstawie tego answer.

Problem polega na tym, że ViewPager nie jest w pełni załadowany, gdy słuchacz jest skonfigurowany, pierwsza strona jest wywoływana, ale fragmenty wewnątrz ViewPager nie zostały jeszcze w pełni zainicjalizowane.

W celu ustalenia, że ​​po prostu zachować zmienną wiedzieć, czy pierwsza strona została wywołana lub nie:

private boolean mFirstPageCalled = false; 

Następnie w słuchacza:

@Override 
public void onPageSelected(int position) { 

    if(mFirstPageCalled) { 
     // Do your thing 
    } else { 
     mFirstPageCalled = true; 
    } 
} 

Ostateczną rzeczą do zrobienia ma obsłużyć pierwszą stronę, która została pominięta, można to zrobić po utworzeniu ViewPager z:

mViewPager.post(new Runnable(){ 
     @Override 
     public void run() { 
      // Do your thing 
     } 
    }); 

W moim przypadku właśnie nazywamy tu obecny fragment pokazał i praca na nim:

Fragment currentFragment = mPagerAdapter.instantiateItem(mViewPager, mViewPager.getCurrentItem()); 
currentFragment.customAction(); 

Sposób post nazywa się tylko raz, więc idealne do obsługi pierwszy przypadek strony.

0

Moje rozwiązanie jest przedłużyć ViewPager

class MyViewPager extends ViewPager { 

    private List<OnPageChangeListener> _Listeners = new ArrayList<>(); 

    public MyViewPager(Context context) { 
     super(context); 
    } 

    public MyViewPager(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public void addOnPageChangeListener(OnPageChangeListener listener) { 
     super.addOnPageChangeListener(listener); 
     _Listeners.add(listener); 
    } 

    @Override 
    public void removeOnPageChangeListener(OnPageChangeListener listener) { 
     super.removeOnPageChangeListener(listener); 
     _Listeners.remove(listener); 
    } 

    @Override 
    public void setCurrentItem(final int item) { 
     if (item != getCurrentItem()) { 
      super.setCurrentItem(item); 
     } else { 
      post(new Runnable() { 
       @Override 
       public void run() { 
        dispatchOnPageSelected(item); 
       } 
      }); 
     } 
    } 

    private void dispatchOnPageSelected(int position) { 
     for (int i = 0, size = _Listeners.size(); i < size; i++) { 
      OnPageChangeListener listener = _Listeners.get(i); 
      if (listener != null) { 
       listener.onPageSelected(position); 
      } 
     } 
    } 
} 
Powiązane problemy