7

我有一个扩展 PreferenceActivity 的活动。

我的主题:android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" 应用于 Manifest 文件中的应用程序级别。

除了“PreferenceCategory”的“PreferenceScreen”元素之外,一切都得到了想要的主题。它们仍然具有默认的黑色背景。简而言之,具有父首选项屏幕的主首选项类别屏幕正在获取主题,但如果我单击任何 PreferenceScreens 以转到其元素首选项(EditText 等),他们没有获得主题......

知道为什么会发生这种情况吗?

结构或preferences.xml 是这样的:

<PreferenceCategory>

    <PreferenceScreen>
        <EditTextPreference>
        ...
        </EditTextPreference>
        <EditTextPreference>
        ...
        </EditTextPreference>
        ...
    </PreferenceScreen>

    <PreferenceScreen>
    ...
    </PreferenceScreen>

</PreferenceCategory>
4

5 回答 5

5

最后我发现了如何以编程方式更改“PreferenceActivity”的主题(通过java代码)

要更改主题,只需这样做:

        @Override
        public void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.Holo_Theme_Light);
        super.onCreate(savedInstanceState);
        }

总是setTheme(R.style.yourtheme);在方法之前调用super.onCreate(savedInstanceState);方法。通过这样做,它将产生如下所示的结果。

在此处输入图像描述

就这样。

setTheme(R.style.yourtheme);如果你在方法之后调用方法super.onCreate(savedInstanceState);,它将产生如下所示的结果。

在此处输入图像描述

注意:嵌套的 PreferenceScreen 无法识别主题。要将主题应用于该嵌套的 PreferenceScreen,您必须为该嵌套的 PreferenceScreen 创建另一个 PreferenceActivity 并setTheme(R.style.yourtheme);在那里调用方法。

于 2013-03-27T11:22:55.697 回答
3

这是早期 Android 版本中的错误(另请参阅http://code.google.com/p/android/issues/detail?id=4611)。

如果我没记错的话,主题并未正确应用于所有 Android 2.x 版本上的 PreferenceActivity。解决此问题的一种方法是自己设置调整颜色/字体等,但错误报告的评论中也描述了一种解决方法。主题应在 Android 3.0 及更高版本上正常工作。

于 2012-04-19T13:58:04.157 回答
3

查看 的源码PreferenceScreen#showDialog(Bundle),我们看到对话框是使用通过 获得的主题资源创建的mContext.getThemeResId(),然后在ContextThemeWrapper.

这可以极大地帮助我们,因为我们所要做的就是覆盖getThemeResId()您的 Activity 中的方法(对公共 API 隐藏),以提供我们的自定义主题,并且子 PreferenceScreen 现在使用我们想要的任何自定义主题资源!

/**
 * This is a hack to provide our own theme for the PreferenceScreen's dialog.
 *
 * @see android.preference.PreferenceScreen#showDialog(Bundle)
 */
// NOTE there is no @Override, even though it overrides the Activity method
public int getThemeResId() {
    return R.style.Theme_MyApp_PreferenceScreen;
}

请注意,由于此方法使用 注释@hide,因此我们不能使用@Override通常在这种情况下使用的注释;而且我们也不能调用该super.getThemeResId()方法。如果您真的非常希望能够有条件地覆盖它并调用超级实现作为后备,您将不得不使用反射来获取超级实现的方法:

        try {
            ((Object) this).getClass().getMethod("getThemeResId").invoke(this);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
于 2014-09-01T21:33:26.520 回答
2

由于所有其他答案都尝试使用 java 代码解决它,这就是我完全使用 xml 并且没有声明我自己的偏好类的方式。

首先,我从这里复制了一个首选项的完整布局,并将所有的更改"@+android:id/xyz""@android:id/xyz". 然后在我的样式文件中,我将新样式声明为:

<style name="preference">
    <item name="android:layout">@layout/source_preference</item>
</style>

现在在 AppTheme 中,一个新的首选项条目:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:textColor">@drawable/text_selector</item>
    <item name="android:preferenceStyle">@style/preference</item>
</style>

现在为这个新布局设置你想要的所有样式。就是这样。

于 2016-07-06T16:05:42.157 回答
0
@Override
public boolean onPreferenceTreeClick(final PreferenceScreen preferenceScreen, final Preference preference) {
    // https://code.google.com/p/android/issues/detail?id=4611 comment #35
    if (preference instanceof PreferenceScreen && ((PreferenceScreen) preference).getDialog() != null)
        ((PreferenceScreen) preference).getDialog().getWindow().getDecorView().setBackgroundColor(Color.parseColor("#ffffff"));

    return super.onPreferenceTreeClick(preferenceScreen, preference);
}
于 2014-01-30T22:03:20.540 回答