[英]android onCreateOptionsMenu called twice when restoring state
這是我創建的一個簡單的Android應用程序來演示我的問題:
public class OptionMenuTest extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("test", "create activity");
setContentView(R.layout.options_layout);
if(getFragmentManager().findFragmentByTag("frag") == null) {
getFragmentManager().beginTransaction().add(R.id.option_fragment_container, new OptionMenuFragment(), "frag").commit();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
Log.d("test", "saving Activity state");
super.onSaveInstanceState(outState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d("test", "create Activity options menu");
menu.add("activity");
return true;
}
}
分段:
public class OptionMenuFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("test", "create fragment");
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
TextView tv = new TextView(getActivity());
tv.setText("Hello world");
Log.d("test", "create fragment view");
return tv;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add("fragment");
Log.d("test", "create fragment options menu");
}
}
Layout只是一個LinearLayout,用於將片段轉儲到:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/option_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</LinearLayout>
很簡單吧? 當我運行它時,我得到了預期的以下輸出:
06-12 15:42:51.415: D/test(957): create activity
06-12 15:42:51.446: D/test(957): create fragment
06-12 15:42:51.446: D/test(957): create fragment view
06-12 15:42:51.446: D/test(957): create Activity options menu
06-12 15:42:51.446: D/test(957): create fragment options menu
現在,當我旋轉手機時,我得到一些奇怪的行為:
06-12 15:43:11.251: D/test(957): saving Activity state
06-12 15:43:11.290: D/test(957): create fragment
06-12 15:43:11.290: D/test(957): create activity
06-12 15:43:11.306: D/test(957): create fragment view
06-12 15:43:11.306: D/test(957): create Activity options menu
06-12 15:43:11.306: D/test(957): create fragment options menu
06-12 15:43:11.306: D/test(957): create Activity options menu
06-12 15:43:11.306: D/test(957): create fragment options menu
為什么onCreateOptionMenu和片段onCreateOptionsMenu上的活動被調用了兩次? 如果我從片段中刪除選項菜單,我會按預期調用onCreateOptionsMenu上的活動:
06-12 15:50:03.610: D/test(1076): create fragment
06-12 15:50:03.610: D/test(1076): create fragment view
06-12 15:50:03.813: D/test(1076): create Activity options menu
06-12 15:50:08.392: D/test(1076): saving Activity state // <-- rotate happens here
06-12 15:50:08.446: D/test(1076): create fragment
06-12 15:50:08.446: D/test(1076): create activity
06-12 15:50:08.462: D/test(1076): create fragment view
06-12 15:50:08.470: D/test(1076): create Activity options menu
我不明白這一點,似乎沒有其他人遇到過這個問題。 真正的問題是我的SearchView無法恢復配置更改(手機旋轉)的狀態,因為onCreateOptionMenu被調用兩次。 它第一次似乎有它的狀態,但第二次被清除並重置。 我無法弄清楚我做錯了什么。
提前致謝。
我想我找到了這個問題的答案。
看看這個:
https://stackoverflow.com/a/7225296/48468
這個問題似乎與Android在活動被銷毀時(旋轉設備時)不破壞碎片的事實有關。
基本上我補充說:
setRetainInstance(true);
到我的片段構造函數,問題就解決了。
希望能幫助到你!
@Gerardo Contijoch的回答是誤導性的,除了一個事實:
在您的示例中, Activity
和Fragment
在輪換時被銷毀並再次創建。 這就是onCreateOptionsMenu()
被調用兩次的原因。 這是正確和預期的行為。
通過setRetainInstance(true)
你告訴Android不要破壞片段。 如果沒有UI的片段沒有Activity的上下文( 對於AsyncTasks協調和一些其他類似服務的東西很有用),這可能會很有用。
在其他情況下碎片這可能會導致內存泄漏,您應該避免。
在充氣和工作之前我剛剛清理了菜單
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.call_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.