这几天笔者在开发一个备忘录的小项目,昨天晚上在给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.