這幾天筆者在開發一個備忘錄的小項目,昨天晚上在給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.