在fragment中設置bar,getSupportActionbar()返回null,添加up action失敗的原因。

這幾天筆者在開發一個備忘錄的小項目,昨天晚上在給APP設置Toolbar的時候,想給bar上加一個回退箭頭的時候,遇到了getSupportActionbar()返回null的問題。
首先是谷歌官方的給bar設置up action的代碼:
在manifest裏:

 <activity
        android:name="com.example.myfirstapp.MainActivity" ...>
        ...
    </activity>

    <!-- A child of the main activity -->
    <activity
        android:name="com.example.myfirstapp.MyChildActivity"
        android:label="@string/title_activity_child"
        android:parentActivityName="com.example.myfirstapp.MainActivity" >

        <!-- Parent activity meta-data to support 4.0 and lower -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />

java裏:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_child);

    // my_child_toolbar is defined in the layout file
    Toolbar myChildToolbar =
        (Toolbar) findViewById(R.id.my_child_toolbar);
    setSupportActionBar(myChildToolbar);

    // Get a support ActionBar corresponding to this toolbar
    ActionBar ab = getSupportActionBar();

    // Enable the Up button
    ab.setDisplayHomeAsUpEnabled(true);
}

有問題問谷歌,筆者翻牆出去搜了一下,一下子搜出一大片相同問題。這些問題無一例外的都是提在stackoverflow上。
綜合了一下上面的解決方案,大致有以下幾個錯誤導致的:
1,代碼寫在了setContentview(…)前面。
2,app Theme沒有設置成無actionbar的theme
3,包導錯了,Actionbar必須是v7 support包裏的

但是筆者檢查了這幾個方面,發現自己的代碼完全正確,但是運行app後就是沒有出現up按鈕。
如果你也有同樣的問題,那麼你有百分之九十可能來對了。

請點開getSuportActionbar()的源碼,會發現是這樣的:

@Nullable
    public ActionBar getSupportActionBar() {
        return getDelegate().getSupportActionBar();
    }

getDelegate()是什麼?delegate委託,這就是一個獲得委託的方法,獲得的是什麼委託?爲什麼要獲得委託?
別急,先分析一下筆者的工程,它主要有兩個界面,分別是一個listfragment和展示明細的fragment,兩個fragment分別託管於兩個不同的activity。
由於這兩個activity不需要特殊的視圖,所以這兩個activity都是用的同一份xml文件。
筆者開始添加toolbar時,是分別在兩個fragment的xml視圖文件裏按谷歌的代碼添加了兩個toolbar,然後在fragment的oncreate代碼裏寫下:

Toolbar myChildToolbar =
        (Toolbar) findViewById(R.id.my_child_toolbar);
    setSupportActionBar(myChildToolbar);

    // Get a support ActionBar corresponding to this toolbar
    ActionBar ab = getSupportActionBar();

    // Enable the Up button
    ab.setDisplayHomeAsUpEnabled(true);

但是運行app後報了一個nullpointerexcption,檢查後發現getSupportActionBar根本就沒有獲得到bar。
筆者又添加了如下代碼:

 Toolbar toolbar = (Toolbar) getactivity().findViewById(R.id.main_delegate_tool);
        System.out.println("toolbar : " + toolbar);

發現toolbar也是null,也就是說,根本沒有加載出toolbar,爲什麼沒有加載出來?
這時候我們再點開源碼,發現源碼裏有一個getDelegate()的方法,getDelegate()在這裏很明顯就是獲得當前fragment委託的activity。
但是,我們的activity的佈局xml裏什麼都沒有,toolbar是寫在fragment的佈局文件裏的,然而fragment是沒有加載toolbar的能力的,所以這時候,就沒辦法獲得toolbar了。也就是findviewbyid最終返回了null,所以就導致我們getsuportactionbar get不到東西,也返回了null。

如果你也遇到相同的問題,並且stackoverflow上所有提到的錯誤都沒有犯,那麼這時你就要考慮一下你的toolbar是寫在fragment的xml文件裏的,能不能被順利的獲得。
所以解決方法也非常簡單,在activity的佈局文件裏添加Toolbar ,不要在fragment的xml文件裏添加Toolbar.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章