2012-05-07 40 views
9

Tôi gặp vấn đề với FragmentStatePageAdapter (mà tôi sử dụng làm bộ điều hợp cho một ViewPager) và các mục menu từ thanh hành động.FragmentStatePageAdapter sao chép các mục menu ActionBar

Khi tôi khởi chạy ứng dụng, mọi thứ đều ổn. Nếu tôi di chuyển tác vụ sang nền (ví dụ, nhấn nút HOME) và tôi bắt đầu thực hiện công việc cho đến khi hoạt động kết thúc, khi tôi quay lại ứng dụng của mình (thông qua trình khởi chạy hoặc thông báo tôi tạo), mọi thứ đều ổn, ngoại trừ các mục menu được sao chép trong thanh tác vụ.

Một chi tiết quan trọng là các mục trùng lặp duy nhất là các mục được tạo trong onCreateOptionsMenu() của từng đoạn tôi sử dụng trong ViewPager.

Nếu tôi replaceFragmentStatePageAdapter với FragmentPageAdapter các mục không được sao chép nữa, nhưng các mảnh không được hiển thị trong ViewPager (hàm getItem() từ bộ điều hợp không bao giờ được gọi sao cho nó không trả về bất kỳ đoạn nào).

Bất kỳ ý tưởng nào? Một cách để tránh FragmentStatePageAdapter để sao chép các mục menu? Có thể sử dụng FragmentPageAdapter nhưng với một sửa đổi để hiển thị các mảnh? Một sửa đổi trong các mảnh của tôi?

Dưới đây là một số đoạn mã từ ứng dụng của tôi ...

Làm thế nào các mục menu được tạo ra bên trong các mảnh vỡ:

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    /* Create play button */ 
    final MenuItem mPlay = menu.add(R.string.play_all); 

    mPlay.setIcon(R.drawable.ic_play_all); 
    mPlay.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 

    mPlay.setOnMenuItemClickListener(new OnMenuItemClickListener() { 
     @Override 
     public boolean onMenuItemClick(MenuItem item) { 
      final List<Song> songs = getSongs(); 

      if (songs.size() == 0) { 
       /* Show message */ 
       Toast.makeText(mContext, R.string.no_song_list, Toast.LENGTH_LONG).show(); 
      } else { 
       /* Play song list */ 
       try { PlayManager.getService().playList(songs); } catch (Exception e) {} 
      } 

      return false; 
     } 
    }); 

    /* Create menu */ 
    super.onCreateOptionsMenu(menu, inflater); 
} 

Làm thế nào mảnh vỡ được khởi tạo trong adapter ViewPager

@Override 
public Fragment getItem(int position) { 
    final Class<?> cls = mTabs.get(position); 

    /* No tab */ 
    if (cls == null) 
     return null; 

    /* Instantiate fragment */ 
    final Fragment fragment = Fragment.instantiate(mContext, cls.getName(), null); 

    /* Add to list */ 
    mFragments.put(position, fragment); 

    /* Return fragment */ 
    return fragment; 
} 

Cảm ơn!

PS: Tôi đã cố gắng thay đổi launchMode của hoạt động thành "singleTop" và tôi cũng đã cố gắng trả về trong getItem() đoạn tạo được ưu tiên (nhưng điều đó vô ích khi getItem() không bao giờ được gọi khi tôi quay lại ứng dụng , như tôi đã nói trước đây).

+0

Xin chào, Miguel! Bạn đã tìm thấy giải pháp? – HighFlyer

+0

Vâng. Tôi vừa đăng dưới giải pháp tôi đã sử dụng. Nó không phải là một sửa chữa thực sự nhưng một workaround. –

Trả lời

3

Tôi đã tìm ra giải pháp cho vấn đề của mình sau vài ngày sau khi đăng sự cố. Tôi xin lỗi vì đã đặt nó ở đây quá muộn.

Các mã sau cố định vấn đề của tôi:

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 

    outState.remove("android:support:fragments"); 
} 

Đơn giản như văn bản rằng đoạn mã trong hoạt động nơi tôi nhanh chóng và sử dụng các mảnh vỡ.

Tôi hy vọng điều này sẽ giúp :)

+0

Tuyệt vời! :) Một giải pháp khác: gọi setRetainInstance (true) trên các phân đoạn trong máy nhắn tin. – HighFlyer

+0

Tôi cũng sẽ phải thử cái đó :) –

+0

Sau khi một số thử nghiệm có vẻ như outState.remove không hoạt động với xoay màn hình, vì FragmentStatePageAdapter sử dụng thông tin này khi trạng thái đang khôi phục. Ngoài ra setRetainInstance (true) không hoạt động với việc khởi chạy ứng dụng từ nền. – HighFlyer

2

Tôi cho rằng vấn đề là FragmentStatePagerAdapter tạo một Phân đoạn mới mỗi khi bạn vuốt. Kết quả là, onCreateOptionsMenu() được gọi cho mỗi Fragment được tạo ra.

Có, tôi nghĩ rằng, hai giải pháp:

  1. Lấy thao tác thanh hành động ra khỏi mảnh vỡ. Thay vì thiết lập một onclick cho mục menu bên trong Fragment, bạn gửi một tin nhắn đến Fragment hiện tại từ Activity.

  2. Sử dụng Menu.findItem() để xem liệu Phân đoạn khác đã thêm MenuItem bạn muốn chưa và nếu có đính kèm Fragment hiện tại vào nó (trong onPrepareOptionsMenu()).

+0

Đó không phải là lý do. Lần đầu tiên tôi khởi chạy ứng dụng và khi tôi vuốt, nó hoạt động hoàn hảo. Khi tôi vuốt, các mục được tạo bởi đoạn tôi di chuyển sẽ bị xóa và các mục từ đoạn tôi di chuyển sẽ được thêm vào. Vấn đề chỉ xảy ra khi hoạt động được đóng trong khi đang ở chế độ nền và tôi bắt đầu lại. –

3

Trước khi lạm phát menu tùy chọn trong Fragment của bạn bên trong ViewPager, kiểm tra xem các ví dụ Fragment có thể nhìn thấy để ngăn chặn các mục menu trùng lặp:

// This should be in your Fragment implementation 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
{ 
    if(isVisible()) 
    { 
     inflater.inflate(R.menu.menu_fragment, menu); 
    } 
    super.onCreateOptionsMenu(menu, inflater); 
} 
+0

Mã của bạn giúp tôi khắc phục sự cố Sao chép nhưng nó không thay đổi phân đoạn. – Roon13

0

Tôi tìm thấy một số giải pháp thử nó có thể làm việc

trong trùng lặp đoạn thực đơn của bạn Thêm menu.clear() trước khi menu file thổi phồng trong onCreateOptionsMenu(Menu menu, MenuInflater inflater)

@Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     menu.clear(); 
     inflater.inflate(R.menu.main,menu); 
    } 
Các vấn đề liên quan