Fragment是Android里面中一個非常靈巧的設(shè)計偏陪,它可以看做ui模塊锹安,由活動托管褥芒。熟練的使用它們能優(yōu)雅的實現(xiàn)很復(fù)雜的界面,而且用它們編寫UI界面又憨,相對于用一個個Activity所消耗內(nèi)存少得多翠霍,而且切換很流暢锭吨,可以參考知乎客戶端。
但是寒匙,F(xiàn)ragment使用過程中會出現(xiàn)一些小問題零如,這里講如何在Fragment中添加menu。我們都知道在活動中添加menu只用編寫好menu锄弱,在onCreateOptionsMenu中加載考蕾,并在onOptionsItemSelected中處理點擊事件就可以了,按照這個流程先試下
首先編寫menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/item_setting"
android:icon="@drawable/ic_settings"
android:title="@string/setting"
app:showAsAction="always"/>
</menu>
這里只添加一個設(shè)置的menu item
然后要加載menu需要toolbar或actionbar会宪,這里分兩種情況:
- 用Activity中actionbar或toolbar肖卧,在Fragment中不添加toolbar
只需在Activity中初始化好標(biāo)題欄(用toolbar時要調(diào)用setSupportActionBar),在fragment中
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main,menu);
super.onCreateOptionsMenu(menu, inflater);
}
- 去除Activity中標(biāo)題欄掸鹅,在Fragment中添加toolbar
在fragment中初始化標(biāo)題欄時要注意塞帐,fragment中沒有setSupportActionBar方法,也就是在標(biāo)題欄還是要交給托管其的活動來處理巍沙,標(biāo)題欄最終設(shè)置到window上葵姥,代碼如下
/**
* Fragment中初始化Toolbar
* @param toolbar
* @param title 標(biāo)題
* @param isDisplayHomeAsUp 是否顯示返回箭頭
*/
public void initToolbar(Toolbar toolbar, String title, boolean isDisplayHomeAsUp) {
AppCompatActivity appCompatActivity= (AppCompatActivity) getActivity();
appCompatActivity.setSupportActionBar(toolbar);
ActionBar actionBar = appCompatActivity.getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(title);
actionBar.setDisplayHomeAsUpEnabled(isDisplayHomeAsUp);
}
}
然后再調(diào)用onCreateOptionsMenu加載到toolbar上
運行一下,你會發(fā)現(xiàn)兩種情況下menu都沒加載出來句携。原來要在fragment中加載menu還需在其onCreate中加一句 setHasOptionsMenu(true)榔幸,用于讓活動知道有menu要加載
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
現(xiàn)在menu加載出來了
然后重寫onOptionsItemSelected處理點擊事件
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_setting:
SettingActivity.start(getContext());
return true;
default:
return super.onOptionsItemSelected(item);
}
}
現(xiàn)在就大功告成了嗎,然而運行后會發(fā)現(xiàn)無論怎么點擊onOptionsItemSelected都沒被調(diào)用矮嫉∠髋兀可以再android training中找到原因
http://developer.android.com/guide/topics/ui/actionbar.html
Note: If you added the menu item from a fragment, via the Fragment class's onCreateOptionsMenu callback, then the system calls the respective onOptionsItemSelected() method for that fragment when the user selects one of the fragment's items. However the activity gets a chance to handle the event first, so the system calls onOptionsItemSelected() on the activity before calling the same callback for the fragment.
也就是說在雖然在fragment中重寫onOptionsItemSelected,但系統(tǒng)會在activity中先調(diào)用onOptionsItemSelected蠢笋,而活動中默認都消耗了點擊事件拨齐,fragment中因此無法處理點擊。所以要先在托管碎片的活動中講frament中處理的menu item返回false挺尿,讓點擊事件能穿到fragment的onOptionsItemSelected中
@Override
public boolean onOptionsItemSelected(MenuItem paramMenuItem) {
switch (paramMenuItem.getItemId()) {
case R.id.item_setting:
return false;
default:
return super.onOptionsItemSelected(paramMenuItem);
}
}
總結(jié)下
要在fragment添加menu需要以下步驟:
- 在fragment的onCreate中添加一句 setHasOptionsMenu(true)奏黑;
- 如果用的是活動的標(biāo)題欄,只需在onCreateOptionsMenu中加載menu编矾;如果用Fragment自己的toolbar需要先用活動初始化toolbar熟史,然后再onCreateOptionsMenu
- 在活動中重寫onOptionsItemSelected,講需要在fragment中處理的menu item直接返回false窄俏,再在fragment的onOptionsItemSelected中處理