PreferenceActivity 中的 ActionBar

Posted

技术标签:

【中文标题】PreferenceActivity 中的 ActionBar【英文标题】:ActionBar in PreferenceActivity 【发布时间】:2011-12-17 06:01:05 【问题描述】:

在我的应用程序中,我使用了来自 Google 的新操作栏兼容性示例(位于 <sdk>/samples/android-<version>/ActionBarCompat),效果很好。我唯一遇到的问题是将其应用于我的PreferenceActivity,以便获得类似于 Android Market 中设置的屏幕(见图)。

要用图标填充ActionBar,每个Activity 必须扩展ActionBarActivity 类。问题是我的Activity 已经扩展了PreferenceActivity 并且在Java 类中不能扩展多个类。

必须有一种方法可以将ActionBarPreferenceScreen 一起获取。如果有人可以为这个常见问题提供解决方案,我会很高兴。

P.S.:像 How to add a button to PreferenceScreen 这样的解决方案不适合,因为 ActionBar 实际上是标题栏,所以这更像是 Java 而不是布局。

【问题讨论】:

看到这个帖子,我想它会对你有所帮助:***.com/questions/2697233/… [1]:***.com/questions/2697233/… 经过大量的修改和反思,熟练的程序员可以做到。我试过了 - 我失败了。 我得到了官方的 PreferenceFragment 工作! 如果你愿意,你可以试试我做的一个库:github.com/AndroidDeveloperLB/MaterialStuffLibrary 【参考方案1】:

编辑:我下面的答案相当老套,现在似乎已经过时了(对于 Android 3.0 之前的版本),请查看其他答案,了解不那么老套和更新的解决方案 ~ pyko 2014-09-01


我设法让它工作 - 不确定这是否是最好/最干净的解决方案,但它有效。

必须进行以下更改:

    复制ActionBarActivity 并让新类扩展PreferenceActivity

    public abstract class ActionBarPreferenceActivity extends PreferenceActivity 
        // contents exactly the same as 'ActionBarActivity'
    
    

    ActionBarHelperBase.java 中稍微修改onCreate() - 为PreferenceActivity 类做一个特例

    @Override
    public void onCreate(Bundle savedInstanceState) 
        // If the activity is a PreferenceActivity, don't make the request
        if (!(mActivity instanceof PreferenceActivity)) 
            mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        
    

    让您的 PreferenceActivity 扩展此类并添加对 FEATURE_CUSTOM_TITLE 的请求 您调用 super.onCreate()

    public class MyPreferenceActivity extends ActionBarPreferenceActivity 
    
        @Override
        protected void onCreate(Bundle savedInstanceState) 
            requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); // add this line
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
            // etc etc
        
    
        // etc etc
    
    

据我所知,需要更改 2 和 3,因为对于 PreferenceActivity

“一旦你调用 super.onCreate(),ViewGroup 就会被设置,所以你不能改变 Window 的参数。” (see Oliver's comment to the answer)

我猜PreferenceActivity 活动中组件的创建顺序与普通的 Activity 活动不同。

【讨论】:

感谢您解决此问题。似乎没有干净的解决方案。我现在将ActionBarSherlock 用于操作栏实现,它提供了比 Android 兼容性操作栏更多的功能。 为了让这个工作我必须检查 android api 版本是否低于 3.0 (= 11) 否则这不起作用。因此,在首选项类中,我必须在 super.onCreate(...) 之前执行此操作: if (ContextUtils.getAndroidApiVersion() 设置一个简单的加载到 PreferenceFragment 中的普通 actionbaractivity 来完成这个。以防其他人来到这里但没有考虑这个简单的解决方案。 当您说“复制ActionBarActivity”时,您的意思是获取源代码并将其复制到我自己的项目中吗?例如,从这里? android.googlesource.com/platform/frameworks/support/+/… 也许这曾经有效,但 appcompat-v7_19.1.0 ActionBarActivity#onCreate 调用 ActionBarActivityDelegate.createDelegate((ActionBarActivity) this)。这意味着您不能传入 PreferenceActivity 子类。【参考方案2】:

如果你想尝试基于 support-v4 Fragment 的 PreferenceFragment 实现:

https://github.com/kolavar/android-support-v4-preferencefragment

我自己使用它,将 PreferenceActivity 转换为 PreferenceFragment 并没有太多工作。

【讨论】:

【参考方案3】:

你能克隆ActionBarActivity的代码,把“扩展Activity”改成“扩展PreferenceActivity”吗?然后扩展您的新类而不是 ActionBarActivity。

不过,在我见过的所有 Google 应用中,将按钮放在 PreferenceActivity 的操作栏中似乎并不常见。如果您没有在其上放置按钮,则可以只使用 values-v11 替代样式资源来显示全息主题,并在 PreferenceActivity 的清单中设置该样式。

【讨论】:

没有,因为ActionBarActivityDelegate【参考方案4】:

我在我的应用程序中使用了这个操作栏 https://github.com/johannilsson/android-actionbar 这个线程很好用 How to add a button to PreferenceScreen

【讨论】:

谢谢。我现在使用ActionBarSherlock,这非常好。这个库的第一个版本使用 johannilsson 的 Actionbar 作为基础。【参考方案5】:

我要感谢@pyko 提供了一个很好的答案,但它的问题是它在 HoneyComb 及更高版本上无法正常工作。好吧,您可以像@AndroidDev 所说的那样有一种破解方法; 但是@pyko 会污染ActionBarHelperBase 类,而@AndroidDev 不是很透明。最好的方法是创建从PreferenceActivity 扩展的ActionBarActivityPreferences;并在 onCreate 方法中,改变调用父方法的顺序:

@Override
protected void onCreate(Bundle savedInstanceState) 
    //IMPORTATNT: MAKE SURE actionBarHelper called before super;
    //as super oncreate of prefenceactivity is actuallying setting the content view
    mActionBarHelper.onCreate(savedInstanceState);
    super.onCreate(savedInstanceState);

为什么调用'mActionBarHelper.onCreate(savedInstanceState);'在'super.onCreate(savedInstanceState);'之前,那是因为super(即PreferenceActivity)实际上是在其onCreate方法中设置内容视图,这会导致崩溃(“必须在添加内容之前调用requestFeature()”)。所以你需要做的是交换顺序,使确定'mActionBarHelper.onCreate(savedInstanceState);'在 super 之前调用。 通过这种方式,我们不需要污染“ActionBarHelperBase”,但我们保持 SettingActivity 非常干净,因为我们将棘手的细节封装到“ActionBarActivityPreferences”并砰!

【讨论】:

【参考方案6】:

您可以通过以下更改轻松地在偏好活动中添加操作栏:

AndroidManifest.xml 中:

<activity
        android:name=".activity.SettingsActivity"
        android:theme="@style/SettingsTheme"
        android:label="Settings"/>

v21/styles.xml

<style name="SettingsTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
    <item name="android:colorPrimary">@color/colorPrimary</item>
    <item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
</style>

v14/styles.xml 中获取 Back API 支持:

<style name="SettingsTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/ActionBar.V14.Movie.NoTitle</item>
</style>

【讨论】:

【参考方案7】:

谢谢,只是一个更新,您需要在自定义标题行之前添加一个 if 语句以支持 HoneyComb 及以上。

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
   requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 

【讨论】:

【参考方案8】:

您可以获得一个 ActionBarSherlock 库并让您编写扩展 SherlockPreference 的代码;

【讨论】:

以上是关于PreferenceActivity 中的 ActionBar的主要内容,如果未能解决你的问题,请参考以下文章

Android之设置页面(PreferenceActivity使用)

PreferenceActivity:将值保存为整数

在 API 15 及更高版本中使用 PreferenceActivity

android中SharedPreferences和PreferenceActivity的存取数据

您如何刷新 PreferenceActivity 以显示设置的更改?

过时的PreferenceActivity导致Fragment显示问题