Đây là vấn đề của tôi. Tôi có một ứng dụng mà tôi đang sử dụng ActionBar Sherlock với các tab, các đoạn với các menu tùy chọn. Mỗi khi tôi xoay trình mô phỏng, các menu được thêm vào cho tất cả các phân đoạn, ngay cả những phần được đặt/xóa (tôi đã thử cả hai).onCreateOptionsMenu đang được gọi quá nhiều lần trong ActionBar bằng cách sử dụng các tab
Đây là cài đặt: Một FragmentActivity, có một ActionBar với
final ActionBar bar = getSupportActionBar();
bar.addTab(bar.newTab()
.setText("1")
.setTabListener(new MyTabListener(new FragmentList1())));
bar.addTab(bar.newTab()
.setText("2")
.setTabListener(new MyTabListener(new FragmentList2())));
bar.addTab(bar.newTab()
.setText("3")
.setTabListener(new MyTabListener(new FragmentList3())));
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowHomeEnabled(true);
bar.setDisplayShowTitleEnabled(true);
Các tab đều sử dụng Listener tương tự:
private class MyTabListener implements ActionBar.TabListener {
private final FragmentListBase m_fragment;
public MyTabListener(FragmentListBase fragment) {
m_fragment = fragment;
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
FragmentManager fragmentMgr = ActivityList.this.getSupportFragmentManager();
FragmentTransaction transaction = fragmentMgr.beginTransaction();
transaction.add(R.id.frmlyt_list, m_fragment, m_fragment.LIST_TAG);
transaction.commit();
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
FragmentManager fragmentMgr = ActivityList.this.getSupportFragmentManager();
FragmentTransaction transaction = fragmentMgr.beginTransaction();
transaction.remove(m_fragment);
transaction.commit();
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
}
Mỗi lớp con của FragmentListBase có thực đơn riêng của mình và do đó tất cả 3 lớp con có:
setHasOptionsMenu(true);
và thích hợp
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.d(TAG, "OnCreateOptionsMenu");
inflater.inflate(R.menu.il_options_menu, menu);
}
Khi tôi chạy ứng dụng tôi có thể thấy rằng onCreateOptionsMenu đang được gọi nhiều lần, cho tất cả các đoạn khác nhau.
Tôi hoàn toàn bối rối.
Tôi đã cố gắng đăng nhiều mã nhất có thể mà không bị áp đảo, nếu bạn thấy có điều gì đó bị thiếu, vui lòng khuyên.
[Chỉnh sửa] Tôi đã thêm ghi nhật ký nhiều hơn và hóa ra đoạn đó đang được đính kèm hai lần (hoặc nhiều hơn) khi xoay vòng. Một điều mà tôi nhận thấy là mọi thứ được gọi nhiều lần ngoại trừ phương thức onCreate() đang được gọi chỉ một lần.
06.704:/WindowManager(72): Setting rotation to 0, animFlags=0
06.926:/ActivityManager(72): Config changed: { scale=1.0 imsi=310/260 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=35}
07.374:/FragmentList1(6880): onAttach
07.524:/FragmentList1(6880): onCreateView
07.564:/FragmentList1(6880): onAttach
07.564:/FragmentListBase(6880): onCreate
07.564:/FragmentList1(6880): OnCreateOptionsMenu
07.574:/FragmentList1(6880): OnCreateOptionsMenu
07.604:/FragmentList1(6880): onCreateView
[Chỉnh sửa 2]
Ok, tôi bắt đầu truy tìm trở lại vào mã Android và tìm thấy phần này ở đây (mà tôi chỉnh sửa để rút ngắn bài này).
/com_actionbarsherlock/src/android/support/v4/app/FragmentManager.java
public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (mActive != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu) {
f.onCreateOptionsMenu(menu, inflater);
}
}
}
Vấn đề là mAdded không thực sự có nhiều trường hợp của FragmentList1 trong nó, vì vậy phương pháp onCreateOptionsMenu() là " chính xác "được gọi là 3 lần, nhưng đối với các trường hợp khác nhau của lớp FragmentList1. Điều tôi không hiểu là tại sao lớp học đó lại được thêm vào nhiều lần ... Nhưng đó là một địa ngục dẫn đầu tốt.
Câu trả lời này quá phức tạp. Chỉ cần di chuyển cuộc gọi đến 'bar.setNavigationMode (ActionBar.NAVIGATION_MODE_TABS)' trước khi thêm tab vào * ActionBar * đã khắc phục được sự cố của tôi. – Phil