2013-06-07 30 views
10

Giới thiệu về đơn đăng ký của tôi
Tôi đang phát triển một ứng dụng lịch. Bạn muốn hiển thị chế độ xem theo tháng với điều hướng vuốt ngang? Điều này có nghĩa là người dùng cuộn vô hạn có thể cuộn sang phải và trái theo tháng này sang bất kỳ ngày/tháng nào của năm bất kỳ. Tôi thấy ViewPager rất sử dụng đầy đủ để đạt được điều này (Tôi thực sự không biết bất kỳ phương pháp nào khác sử dụng đầy đủ) .Và bằng cách nhấn vào một người dùng ô ngày có thể xem chi tiết hoặc các sự kiện được thêm vào ngày đó (I don ' t muốn liên kết với lịch thiết bị).Cách thêm trang vào đầu ViewPager?

Về vấn đề
tôi có thể thêm trang mới vào cuối Xem pager của tôi mà không bất kỳ problem.But Nếu người dùng swipes sang trái tôi cần thêm một trang để đầu ViewPager tôi. . Khi tôi thêm trang vào đầu (vị trí chỉ mục bằng 0), trang này sẽ thay thế trang hiện tại của tôi ở vị trí 0 và chỉ có thể thêm một trang (Không có trang mới nào được thêm vào Tôi không biết tại sao). Và sau khi thêm trang vào vị trí zero Tôi không thể thêm thậm chí thêm trang đến cuối xem pager khi người dùng swipes sang phải và reachees trang quân cuối cùng gần xảy ra với một lỗi:

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 

Trong đơn giản câu
Tôi muốn biết cách nào đúng để thêm trang vào đầu và kết thúc của Trình xem trang?

Hoạt động và Adaptor

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(); 
     } 


    } 
} 

lớp Fragment My

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

Trả lời dưới đây là một cách tốt đẹp nhưng thats không thêm một trang vào đầu của máy nhắn tin xem, xin vui lòng giúp tôi để sắp xếp ra vấn đề này, hoan nghênh tất cả để chia sẻ ý tưởng của bạn .... –

+0

bạn đã tìm thấy giải pháp nào? tôi có chung vấn đề đó. tnx để chia sẻ – mehdok

Trả lời

3

tôi sẽ giải thích ở đây cách tôi đã làm nó trong trường hợp của tôi, tôi thêm vào thiết lập cùng một điều, ngoại trừ việc tôi cần phải vuốt sang trái và phải giữa các ngày và không phải tháng:

  1. Tôi thiết lập ngày tối thiểu và ngày tối đa sẽ trở thành giới hạn cho ngày điều hướng. Trong trường hợp của tôi, tôi đặt những giới hạn lớn, từ năm 1970 đến năm 2050 để chắc chắn tôi xử lý đủ thời gian. Nếu chúng ta có một ví dụ dễ dàng hơn với các tháng, giả sử 2012 đến 2014, điều đó có nghĩa là chúng ta sẽ có 3 năm * 12 tháng = 36 vị trí khác nhau có sẵn trong máy nhắn tin.

  2. Khi ứng dụng bắt đầu, theo mặc định, đoạn hiện tại của tôi hiển thị ngày hiện tại, có nghĩa là cho bạn, tháng hiện tại. Vì vậy, tôi đã tạo một chức năng cụ thể trên ứng dụng của mình để có được vị trí bên trong dòng thời gian của tôi để có được vị trí của ngày được chọn trong đó. Nếu chúng ta lấy lại ví dụ trên, vị trí do đó sẽ được 18.

Để cung cấp cho bạn một ý tưởng, ở đây là làm thế nào tôi có được vị trí ngày hiện tại của tôi Activity:

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

daysBetween là một hàm từ thư viện Thời gian Joda, tôi sử dụng nó để lấy số ngày giữa ngày tối thiểu và ngày được chọn (tức là vị trí trong dòng thời gian).

Sau đó, trong chức năng onCreate của tôi, tôi khởi tạo pager cách này trong quá trình tạo Hoạt động:

pager.setCurrentItem(mApplication.getTodayPosition()); 

Đây là bộ chuyển đổi, trong trường hợp nó truyền cảm hứng cho bạn:

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()); 
} 
} 

tôi không đảm bảo nó là giải pháp tốt nhất, nhưng ít nhất nó đang hoạt động.

+0

Cảm ơn bạn Yoann, tôi nghĩ rằng bạn có một số lượng lớn các trang sau đó về hiệu suất, bạn có cảm thấy sự khác biệt về hiệu suất đáng chú ý hay không, chắc chắn tôi sẽ thử đề xuất của bạn ... Cảm ơn bạn :) –

+1

Tốc độ là tốt, bạn phải sử dụng 'FragmentStatePagerAdapter' chứ không phải' FragmentPagerAdapter'. Việc đầu tiên là tốt hơn để xử lý số lượng lớn các trang, nó sẽ giữ trong bộ nhớ chỉ các mảnh hoạt động: http://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html –