【问题标题】:ActionBar in PreferenceActivityPreferenceActivity 中的 ActionBar
【发布时间】: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 而不是布局。

【问题讨论】:

标签: java android android-layout android-actionbar android-preferences


【解决方案1】:

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


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

必须进行以下更改:

  1. 复制ActionBarActivity 并让新类扩展PreferenceActivity

    public abstract class ActionBarPreferenceActivity extends PreferenceActivity {
        // contents exactly the same as 'ActionBarActivity'
    }
    
  2. 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);
        }
    
  3. 让您的 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 的代码;

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多