2013-06-07 11 views
10

O mojej aplikacji
Zajmuję się tworzeniem aplikacji kalendarza. Czy chcesz wyświetlać miesiąc z poziomymi liniami przewijania? Oznacza to, że nieskończenie przewijany Użytkownik może przewijać w prawo i lewo, miesiącem, do dowolnej daty/miesiąca dowolnego roku. Zauważyłem, że ViewPager jest bardzo użyteczny, aby to osiągnąć (nie mam pojęcia, co to jest inne wykorzystanie wszystkich metod). W tym celu, klikając na komórkę z datą, użytkownik może zobaczyć szczegóły lub wydarzenia dodane do tej daty (ja nie wiem). t chcesz połączyć się z kalendarzem urządzenia).Jak dodać stronę na początek okna ViewPager?

O numerze
jestem w stanie dodać nową stronę do końca moim zdaniem pagera bez problem.But Jeśli użytkownik przejeżdża w lewo muszę dodać stronę do początku mojego ViewPager. . Kiedy dodam stronę do początku (pozycja indeksu zera) to zastąpi moją bieżącą stronę na pozycji zero i tylko będzie w stanie dodać jedną stronę (Nie dodałem nowych stron Nie wiem dlaczego). I po dodaniu strony na pozycji zerowej nie jestem w stanie dodać jeszcze dodać stronę do końca widokiem na pager, gdy użytkownik przejeżdża do prawej i reachees ostatnia strona Siła blisko wystąpić błąd:

java.lang.IllegalStateException: Can't change tag of fragment MyFragment{40526bb8 #2 id=0x7f070000 android:switcher:2131165184:2}: was android:switcher:2131165184:2 now android:switcher:2131165184:3 

W prosty zdanie
Chcę wiedzieć, jaki jest właściwy sposób dodawania stron do początku i końca widoku pagera?

Kod

aktywny i Adapter

public class PageViewActivity extends FragmentActivity { 

    ViewPager pager; 
    MyPageAdapter pageAdapter; 
    ArrayList<Fragment> fragments; 

    int page_num = 0; 
    int current_page = 1; 
    int selected_page = 1; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_page_view); 

     pager = (ViewPager) findViewById(R.id.viewpager); 

     fragments = getFragments(); 

     pageAdapter = new MyPageAdapter(getSupportFragmentManager(), pager, 
       fragments); 

     pager.setAdapter(pageAdapter); 
     pager.setCurrentItem(2); 
     pager.setOnPageChangeListener(new OnPageChangeListener() { 

      @Override 
      public void onPageSelected(int arg0) { 

       // setting the selected page index 
       selected_page = arg0;  
       //calling add page 
       addPage(); 

      } 

      @Override 
      public void onPageScrolled(int arg0, float arg1, int arg2) { 
       // TODO Auto-generated method stub   

      } 

      @Override 
      public void onPageScrollStateChanged(int arg0) { 
       // TODO Auto-generated method stub 
      } 
     }); 


    } 

    public int addPage() { 

     System.out.println("Add page called "+selected_page); 
     // checking if selected page is second last and if tru adds new page 
     if (selected_page >= (pageAdapter.getCount() - 1)) {  

      System.out.println("on first condition"); 

      Fragment new_fragment = MyFragment.newInstance("Added to last "+ (pageAdapter.getCount() + 1)); 
      //pageAdapter.fragments.add(pageAdapter.getCount(), new_fragment); 
      System.out.println("pageAdapter.getCount() : "+pageAdapter.getCount()); 
      pageAdapter.add(pageAdapter.getCount(), new_fragment); 
      current_page = selected_page;   
      pageAdapter.notifyDataSetChanged(); 
      System.out.println("New page added"); 
     }else if((selected_page-1)<=0){ 

      System.out.println("on second condition"); 

      Fragment new_fragment = MyFragment.newInstance("Added to begning "+ (pageAdapter.getCount() + 1));   
      pageAdapter.add(0, new_fragment); 
      current_page = selected_page;   
      //pageAdapter.notifyDataSetChanged(); 
     } 

     return pageAdapter.getCount(); 


    } 

    private ArrayList<Fragment> getFragments() { 

     ArrayList<Fragment> fList = new ArrayList<Fragment>(); 

     fList.add(MyFragment.newInstance("Fragment 1")); 
     fList.add(MyFragment.newInstance("Fragment 2")); 
     fList.add(MyFragment.newInstance("Fragment 3")); 
     fList.add(MyFragment.newInstance("Fragment 4")); 
     fList.add(MyFragment.newInstance("Fragment 5")); 

     return fList; 
    } 

    private class MyPageAdapter extends FragmentPagerAdapter { 

     private ArrayList<Fragment> fragments; 
     private ViewPager mPager; 

     public MyPageAdapter(FragmentManager fm, ViewPager vp, 
      ArrayList<Fragment> fragments) { 
      super(fm); 
      this.fragments = fragments; 
      this.mPager = vp; 


     } 

     public void add(int position,Fragment f){   
      fragments.add(position, f); 
      this.notifyDataSetChanged(); 
     } 


     @Override 
     public Fragment getItem(int position) { 
      return this.fragments.get(position); 
     } 

     @Override 
     public int getCount() { 
      return this.fragments.size(); 
     } 


    } 
} 

Moja klasa Fragment

public class MyFragment extends Fragment { 
public static final String EXTRA_MESSAGE = "EXTRA_MESSAGE"; 

public static final MyFragment newInstance(String message) 
{ 
    MyFragment f = new MyFragment(); 
    Bundle bdl = new Bundle(1); 
    bdl.putString(EXTRA_MESSAGE, message); 
    f.setArguments(bdl); 
    return f; 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState) { 

    String message = getArguments().getString(EXTRA_MESSAGE); 
    View v = inflater.inflate(R.layout.myfragment_layout, container, false); 
    TextView messageTextView = (TextView)v.findViewById(R.id.textView); 
    messageTextView.setText(message); 

    //return null; 
    return v; 
} 


} 
+0

Odpowiedź poniżej jest dobrym pomysłem, ale to nie dodaje strony do pagera początku widoku, proszę pomóż mi rozwiązać ten problem, z zadowoleniem przyjmuje wszystkich do dzielenia się swoimi pomysłami .... –

+0

znalazłeś jakieś rozwiązanie? Mam dokładnie ten sam problem. tnx za udostępnianie – mehdok

Odpowiedz

3

opiszę tu sposób, w jaki zrobił to w moim przypadku, dodaję do Setup to samo, z wyjątkiem tego, że musiałem przesuwać w lewo i prawo między dniami a nie miesiącami:

  1. Ustawiam minimalną datę i maksymalną datę, która stanie się limitem dla dat do nawigacji. W moim przypadku nakładam duże limity, od 1970 do 2050, aby mieć pewność, że poradzę sobie z wystarczającą liczbą osi czasu. Jeśli przyjmiemy prostszy przykład z miesięcy, powiedzmy 2012 do 2014, oznacza to, że będziemy mieć 3 lata * 12 miesięcy = 36 różnych pozycji dostępnych w pagera.

  2. Kiedy aplikacja się uruchamia, domyślnie mój bieżący fragment wyświetla bieżący dzień, co oznacza dla ciebie bieżący miesiąc. Dlatego utworzyłem specjalną funkcję w mojej aplikacji, aby uzyskać pozycję na osi czasu, aby uzyskać pozycję wybranej w niej daty. Jeśli znowu weźmiemy przykład powyżej, pozycja będzie zatem 18.

Aby dać wyobrażenie, jak tu jest uzyskać aktualną pozycję dzień w moim Activity:

//position in the timeline 
todayPosition = Days.daysBetween(new DateTime(MIN_DATE), new DateTime(getTodayDate())).getDays(); 

daysBetween jest funkcja z biblioteki Czas Jody, używam jej, aby uzyskać liczbę dni między datą minimalną a wybraną datą (tj. pozycję na osi czasu).

Wtedy w moim onCreate funkcji zainicjować pagera ten sposób podczas tworzenia aktywny:

pager.setCurrentItem(mApplication.getTodayPosition()); 

Oto adapter, w przypadku, gdy cię inspiruje:

public class MyFragmentPagerAdapter extends FragmentStatePagerAdapter{ 

private final int todayPosition; 
private MyFragment currentFragment; 
private final Calendar todayDate; 

/** Constructor of the class */ 
public MyFragmentPagerAdapter(FragmentManager fm, int today_position, Calendar today_date) { 
    super(fm); 
    todayPosition = today_position; 
    todayDate = (Calendar) today_date.clone(); 
} 

/** This method will be invoked when a page is requested to create */ 
@Override 
public Fragment getItem(int arg0) {  
    currentFragment = new MyFragment(); 
    Bundle data = new Bundle(); 

    data.putInt("current_page", arg0); 
    currentFragment.setArguments(data); 
    return currentFragment; 
} 

/** Returns the number of pages */ 
@Override 
public int getCount() {  
    return MyApplication.TOTAL_NUMBER_OF_DAYS; 
} 

@Override 
public CharSequence getPageTitle(int position) { 
    Calendar newDate = (Calendar) todayDate.clone(); 

    int diffDays = position - todayPosition; 
    newDate.add(Calendar.DATE, diffDays); 

    return MyApplication.dateTitleFormat.format(newDate.getTime()); 
} 
} 

nie wiem zagwarantować, że jest to najlepsze rozwiązanie, ale przynajmniej działa.

+0

Dziękuję Yoann, myślę, że masz dużą liczbę stron, a co z wydajnością, czy odczuwasz jakąś zauważalną różnicę w wydajności, Zdecydowanie spróbuję twoich sugestii ... Dziękuję :) –

+1

Szybkość jest dobra, musisz użyć 'FragmentStatePagerAdapter', a nie' FragmentPagerAdapter'. Ten pierwszy lepiej radzi sobie z dużą liczbą stron, zachowa w pamięci tylko aktywne fragmenty: http://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html –

Powiązane problemy