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

这几天笔者在开发一个备忘录的小项目,昨天晚上在给APP设置Toolbar的时候,想给bar上加一个回退箭头的时候,遇到了getSupportActionbar()返回null的问题。
首先是谷歌官方的给bar设置up action的代码:
在manifest里:

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

    
    <activity
        android:name="com.example.myfirstapp.MyChildActivity"
        android:label="@string/title_activity_child"
        android:parentActivityName="com.example.myfirstapp.MainActivity" >

        
        <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.

你可能感兴趣的:(Android开发中的坑)