Fragment中添加menu

Fragment是Android里面中一個(gè)非常靈巧的設(shè)計(jì),它可以看做ui模塊,由活動托管。熟練的使用它們能優(yōu)雅的實(shí)現(xiàn)很復(fù)雜的界面,而且用它們編寫UI界面,相對于用一個(gè)個(gè)Activity所消耗內(nèi)存少得多,而且切換很流暢,可以參考知乎客戶端。

但是,F(xiàn)ragment使用過程中會出現(xiàn)一些小問題,這里講如何在Fragment中添加menu。我們都知道在活動中添加menu只用編寫好menu,在onCreateOptionsMenu中加載,并在onOptionsItemSelected中處理點(diǎn)擊事件就可以了,按照這個(gè)流程先試下

首先編寫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>

這里只添加一個(gè)設(shè)置的menu item

然后要加載menu需要toolbar或actionbar,這里分兩種情況:

  1. 用Activity中actionbar或toolbar,在Fragment中不添加toolbar
    只需在Activity中初始化好標(biāo)題欄(用toolbar時(shí)要調(diào)用setSupportActionBar),在fragment中
@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_main,menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
  1. 去除Activity中標(biāo)題欄,在Fragment中添加toolbar
    在fragment中初始化標(biāo)題欄時(shí)要注意,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上

運(yùn)行一下,你會發(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處理點(diǎn)擊事件

@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)在就大功告成了嗎,然而運(yùn)行后會發(fā)現(xiàn)無論怎么點(diǎn)擊onOptionsItemSelected都沒被調(diào)用??梢栽賏ndroid 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,而活動中默認(rèn)都消耗了點(diǎn)擊事件,fragment中因此無法處理點(diǎn)擊。所以要先在托管碎片的活動中講frament中處理的menu item返回false,讓點(diǎn)擊事件能穿到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需要以下步驟:

  1. 在fragment的onCreate中添加一句 setHasOptionsMenu(true);
  2. 如果用的是活動的標(biāo)題欄,只需在onCreateOptionsMenu中加載menu;如果用Fragment自己的toolbar需要先用活動初始化toolbar,然后再onCreateOptionsMenu
  3. 在活動中重寫onOptionsItemSelected,講需要在fragment中處理的menu item直接返回false,再在fragment的onOptionsItemSelected中處理
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,922評論 25 709
  • 總結(jié) Fragment初始化用newInstance viewPager開多Fragment, 考慮懶加載 get...
    我不是死胖子閱讀 827評論 0 4
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,317評論 0 17
  • 過年七天假,轉(zhuǎn)瞬而逝,朋友圈有位仁兄說,“要返城務(wù)工了”。很逗,又很貼切。 在校園里時(shí),寒暑假都很長,在家待半把月...
    橘子91閱讀 673評論 0 0
  • 圖片發(fā)自簡書App 健康導(dǎo)語 濕邪,可說是現(xiàn)代人健康的最大敵人之一,10個(gè)人里有八九個(gè)人有濕邪潛伏。 生活中很多人...
    黃耀毅閱讀 470評論 0 0

友情鏈接更多精彩內(nèi)容