Android:Fragmnet with custom MenuItem
這是個很簡單的問題,但是常常會忘記設參數,導致即使設定好 MenuItem 與 Lintener 之後還是沒有 Menu 出現,所以決定寫篇來記錄。
情境
做 App 時會有需求是在某個 Activity 下的 fragment-a 有三個 menuItem,而 fragment-b 只需要兩個 menuItem,同時可能該 Activity 也有自己的 Menu 群。如下圖:
基本上有幾種做法,大致上是這樣:
- 以 XML 定義全部 MenuItem,使用 visibility 屬性做控制
- 動態產生
- ...
兩個方式差異不大,相信大家可以自己摸索出來。我們來談談第一種方式,思路大致如下:
- activity 有自己的 menu.xml,其中列出該 activity 全部 fragemnt 會用到的按鈕
- 把 activity 用不到的全都設為 invisibile
- 等切換到特定 fragemnt 時再呼叫 setVisibie() 調整 menu
設定 fragemnt 使用 MenuItem
這時候首先最最重要的是要在 fragment 的 onCreateView
section 中設定 setHasOptionsMenu(true);
這個參數,你心愛的 MenuItem 才會千呼萬喚始出來 --- 這也是我每次幾乎都會忘記做的步驟。
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_alert_list, container, false); setHasOptionsMenu(true); return setupComponents(v); }
Overriding
接下來就很單純了,覆寫 fragment 的 onCreateOptionsMenu
產生與 onOptionsItemSelected
,
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); itemSearch = menu.findItem(R.id.action_search); itemSearch.setVisible(true); }
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_search: // do something break; } return super.onOptionsItemSelected(item); }
Ref
Ref#1 有另外一種不太相同的作法,大致上是把 menuItem 設 group 並設定 visibility。正在閱讀本文的你或許可以參考看看。