2011-09-16 30 views
23

Tôi đang sử dụng một ViewPager cùng với một FragmentPagerAdapter để lưu trữ ba mảnh khác nhauThay thế đoạn với một mảnh bên ViewPager

[Fragment1][Fragment2][Fragment3] 

Những gì tôi đang cố gắng để đạt được là để thay thế thành công Fragment1 với một mảnh hoàn toàn mới, Fragment4, nếu một nhiệm vụ cụ thể thành công.

Khi tôi sử dụng ..

FragmentManager fragmentManager = getSupportFragmentManager(); 
FragmentTransaction transaction = fragmentManager.beginTransaction(); 
transaction.replace(R.id.fragment1_layout_id, fragment4); 
transaction.commit(); 

..the đoạn được thay thế đẹp và Fragment4 được hiển thị thay vì Fragment1. Mặc dù ngay sau khi tôi vuốt tất cả các cách để Fragment3 và sau đó trở lại Fragment4, Fragment1 đã trở lại.

Sau đó, một lần nữa, nếu tôi sử dụng ..

FragmentManager fragmentManager = getSupportFragmentManager(); 
FragmentTransaction transaction = fragmentManager.beginTransaction(); 
transaction.remove(fragment1); 
transaction.commit(); 

..Fragment1 được lấy ra và khi tôi quay trở lại Fragment4 là ở đó. Vì vậy, vấn đề với giải pháp này là tôi không thể tìm thấy một cách để ngay lập tức hiển thị Fragment4 như Fragment1 được lấy ra, ngay cả khi tôi đã cố gắng:

transaction.add(fragment4); 
transaction.show(fragment4); 

Và dưới đây là cách thực hiện FragmentPagerAdapter của tôi trông như thế vào lúc này, không bất kỳ giao dịch nào quản lý:

public static class PagerAdapter extends FragmentPagerAdapter { 

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

    @Override 
    public int getCount() { 
     return VIEW_COUNT; 
    } 

    @Override 
    public Fragment getItem(int position) { 

     Fragment fragment = null; 

     switch (position) { 
     case 0: 
      fragment = Fragment1.newInstance(context_); 
      break; 

     case 1: 
      fragment = Fragment2.newInstance(context_); 
      break; 

     case 2: 
      fragment = Fragment3.newInstance(context_); 
      break; 

     default: 
      break; 
     } 

     return fragment; 
    } 
} 

Chỉnh sửa.

Vì vậy, có vẻ như tôi không hoàn toàn rõ ràng với câu hỏi của mình. Tôi quyết định loại bỏ tất cả các spaghetti tôi quản lý để tạo ra trước đó và cố gắng để nói rằng tôi đã rời chúng đi (xem văn bản in đậm ở trên).

Dù sao đây là khá nhiều những gì tôi đã cố gắng để làm bên GetItem():

@Override 
public Fragment getItem(int position) { 

    Fragment fragment = null; 

    switch (position) { 
    case 0: 

     if (!app.isUserLoggedIn) { 
      if (loginFragment_ == null) { 
       loginFragment_ = LoginFragment.newInstance(context_); 
       transaction_ = fragmentManager_.beginTransaction(); 

       if (logoutFragment_ != null) { 
        transaction_.remove(logoutFragment_); 
        logoutFragment_ = null; 
       } 

       transaction_.add(loginFragment_, "login"); 
       transaction_.commit(); 
      } 

      if (fragmentManager_.findFragmentByTag("login") == null) 
       fragment = LoginFragment.newInstance(context_); 
      else 
       fragment = fragmentManager_.findFragmentByTag("login"); 

     } else { 
      if (logoutFragment_ == null) {      
       logoutFragment_ = LogoutFragment.newInstance(context_); 
       transaction_ = fragmentManager_.beginTransaction(); 

       if (loginFragment_ != null) { 
        transaction_.remove(loginFragment_); 
        loginFragment_ = null; 
       } 

       transaction_.add(logoutFragment_, "logout"); 
       transaction_.commit(); 
      } 

      if (fragmentManager_.findFragmentByTag("logout") == null) 
       fragment = LogoutFragment.newInstance(context_); 
      else 
       fragment = fragmentManager_.findFragmentByTag("logout"); 
     } 
     break; 

    case 1: 
     fragment = HomeFragment.newInstance(context_); 
     break; 

    case 2: 
     fragment = RegisterFragment.newInstance(context_); 
     break; 

    default: 
     break; 
    } 

    return fragment; 
} 

Với mã này, tôi nhận được gì thực hiện, nhưng nếu ai đó nhìn thấy những gì tôi đang làm sai và muốn chỉ tôi đi đúng hướng, tôi đánh giá cao nó rất nhiều!

+0

Tôi nghĩ bạn nên thay đổi getItem trong PagerAdapter. Có mảnh bị trả lại mà phải được nhìn thấy. – pawelzieba

+0

@dziobas Đó là chính xác nơi tôi đã cố gắng để làm phép thuật tôi mô tả trong câu hỏi của tôi, không có may mắn. – velu

+0

fragment2 được gọi khi tôi nhấp vào tab1, tôi không biết tại sao tab2 được gọi? lỗi bộ điều hợp là gì? –

Trả lời

10

Hãy thử sử dụng FragmentStatePagerAdapter

http://android-developers.blogspot.com/2011_08_01_archive.html

coz nó sẽ loại bỏ các mảnh vỡ khi bạn vuốt qua xem (cũng có khi bạn gọi GetItem), do đó bạn không cần phải loại bỏ một cách rõ ràng chúng mình.

Tôi đã gặp phải sự cố tương tự với nó.

Tôi thử mã của bạn và xóa khối if (fragment!=null) và nó hoạt động.

+0

Bạn có thể hiển thị một số mã không. Tôi sẽ rất biết ơn, bởi vì tôi đã làm theo các bước của bạn và tôi đã không nhận được rằng tôi muốn ... – cesards

0

Tuyên bố getItem của bạn có thể trả về fragment4 cho case 0 trong một số trường hợp không?

+0

Có, nó nên và tôi đã cố gắng để tìm ra cách chính xác để làm điều đó cả ngày dài. Tôi đã cập nhật câu hỏi của mình và thêm vào cách tôi đã cố gắng làm điều đó cho đến nay. – velu

0

Hey tôi đã giải quyết vấn đề này bằng cách sử dụng Danh sách bên trong FragmentPagerAdapter của tôi để xử lý các phần khác nhau và sau đó getItem của tôi giống như vậy ....

public void addScreen(String tag, Class<?> clss, Bundle args){ 
     if(clss!=null){ 
      TabInfo info = new TabInfo(tag, clss, args); 
      screens.add(info); 
     } 
    } 
@Override 
    public Fragment getItem(int position) { 
     TabInfo info = screens.get(position); 
     return Fragment.instantiate(context, info.clss.getName(), info.args); 
    } 

Sau đó tôi lập trình xóa/thêm/sắp xếp lại danh sách các mục (mảnh) sau đó gọi vào handler

mAdapter.notifyDataSetChanged() 
3

Giống như Maurycy nói, bạn cần phải gọi mAdapter.notifyDataSetChanged() bất cứ khi nào bạn muốn nói với các ViewPager rằng các mảnh vỡ đã được thay thế. Tuy nhiên, bạn cũng cần ghi đè hàm trừu tượng getItemPosition() trong bộ điều hợp của mình và trả về POSITION_NONE khi được gọi với một đối số cũ, được ẩn, là phân đoạn. Nếu không, ViewPager sẽ giữ lại tất cả các mảnh hiện tại.

Để biết thêm thông tin và mã ví dụ, hãy xem this answer đến related question.

0

Vui lòng xem số answer của tôi cho câu hỏi tương tự về cách chèn/thay thế các tab bằng ViewPagerFragmentPagerAdapter.

0

Hãy thử thiết lập offScreenPageLimit thành 5 (hoặc dựa trên usecase) để tránh tải lại đoạn sao cho những gì bạn đã thay thế sẽ ở lại thay vì tải lại khi bạn vuốt.

mViewPager.setOffscreenPageLimit(5); 
Các vấn đề liên quan