在PreferenceActivity (AppCompat-v7 21)中,getActionBar()返回null

24
在v20 SDK示例中,我已经在PreferenceActivity中实现了DoneBar(操作栏中的两个按钮),但是在更新SDK和AppCompat到版本21后,我的应用崩溃了。

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayOptions(int, int)' on a null object reference

这是因为getActionBar()返回null。而在ActionBarActivity中没有getSupportActionBar()

所以我的问题是如何在PreferenceActivity中获取该操作栏对象,以便我可以在其上应用自定义视图?

解决方案:

经过一些研究,我使用PreferenceFragmentActionBarActivity解决了这个问题,以便我可以调用getSupportActionBar()


3
嗨,你能否创建一篇包含解决方案代码的答案?我目前遇到了相同的问题,但无法真正找出问题出在哪里。 - user409460
4个回答

18

我通过为我的设置活动指定自定义主题来解决了这个问题。

<style name="SettingsTheme" parent="style/Theme.AppCompat.Light">
    <item name="android:windowNoTitle">false</item>
    <item name="android:windowActionBar">true</item>
</style>

在清单文件中的 activity 中添加 android:theme="@style/SettingsTheme",可以控制界面主题。

在 KITKAT 和 LOLIPOP 上再次显示 actionbar(我尚未测试),并且返回到 API v11。我已经测试过,在 API 10 上可以正常工作(没有 actionbar,如预期)。

从 LOLIPOP 上的调试中,PhoneWindow.java:3243 中设置了 FEATURE_NO_TITLE

   if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
        requestFeature(FEATURE_NO_TITLE);

它会删除FEATURE_ACTION_BAR功能。

[编辑]

但是这个操作栏不是来自材质设计主题,所以还不完美。

[编辑2]

我放弃使用标题了,现在我正在使用来自Github的PreferenceFragment。现在所有我的操作栏在升级到AppCompact 21后都是相同的。


2
哪个是正确的。除非您的Activity扩展了ActionBarActivity,否则不要使用Theme.AppCompat - Chris Banes
2
@ChrisBanes 好的,如果我想在我的偏好设置中使用ActionBar,则应该使用带有PreferenceFragment的ActionBarActivity。PreferenceActivity中的ActionBar已过时且自21版本以后不再支持?你能建议一下如何在ActionBarActivity中使用PreferenceFragment实现标题吗?我目前使用loadHeadersFromResource。 - marcinj
我不明白为什么这个正确答案被踩了(所以我点了个赞)。 - mindex

15

如xXx所请求,我提供了我是如何做的例子:

public class SettingsActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Display the fragment as the main content.
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();

        // use action bar here
        ActionBar actionBar = getSupportActionBar();
    }

    public static class SettingsFragment extends PreferenceFragment {
        @Override
        public void onCreate(Bundle paramBundle) {
            super.onCreate(paramBundle);
            addPreferencesFromResource(R.xml.pref_settings);
        }
    }

}

我可以在PreferenceActivityonBuildHeaders()方法中使用这个来处理头部XML文件吗? - mars3142
你用了什么主题? - Jorgesys
1
请注意,在 API > 11 上,您可以使用不支持 PreferenceFragment 和 ActionBarActivity 的组合。只需使用 getFragmentManager() 将其添加即可。这对我非常有效。对于早期版本的 Android,我想唯一的方法就是使用来自 GitHub 的一些后向兼容的 PreferenceFragment。 - dimsuz
当嵌套的“PreferenceScreen”被显示时,操作栏会被移除。是否有任何解决方案适用于appcompat-v7 21? - Petrakeas

7

getActionBar() 在使用 ActivityFragmentActivity 时在 API 5.0 中返回 null。

解决方法是扩展至 ActionBarActivity

public class MainActivity extends ActionBarActivity {

在使用ActionBarActivityappcompat-v7)时,您必须使用getSupportActionBar()


1
通过这样做解决了问题,你的styles xml应该是这样的。

res/values/style.xml

<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:windowDisablePreview">true</item>
    <item name="android:windowActionBar">true</item>
    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>

res/values-v11/style.xml

<style name="AppBaseTheme" parent="android:Theme.Holo.Light"> 
        <!-- API 11 theme customizations can go here. -->
    </style>

res/values-v14/style.xml

<style name="AppBaseTheme" parent="android:Theme.Holo.Light"> 
        <!-- API 11 theme customizations can go here. -->
    </style>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接