How to apply theme to <PreferenceScreen> elements of a <PreferenceCategory>

霸气de小男生 提交于 2019-11-30 15:40:30

问题


I have an activity that extends PreferenceActivity.

My theme : android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" is applied to the application level in the Manifest file.

Everything is getting the desired theme except the "PreferenceScreen" elements of "PreferenceCategory". They are still having the default black background. In simple words, the main Preference Category screen which has the parent Preference Screens are getting the theme but if I click on any of the PreferenceScreens to go to their element preferences(EditText etc etc), they are not getting the theme...

Any Idea why this might be happening?

The structure or preferences.xml is something like this :

<PreferenceCategory>

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

    <PreferenceScreen>
    ...
    </PreferenceScreen>

</PreferenceCategory>

回答1:


It's a bug in earlier Android versions (see also http://code.google.com/p/android/issues/detail?id=4611).

If I remember correctly themes aren't properly applied to a PreferenceActivity on all Android 2.x versions. One way to fix this is to set adjust the colors/fonts etc. yourself, but there is also a workaround described in the comments of the bugreport. Themes should work properly on Android 3.0 and later.




回答2:


At last i found out how to change theme of "PreferenceActivity" programmatically(via java code)

To change theme just do like this:

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

Always call setTheme(R.style.yourtheme); method before super.onCreate(savedInstanceState); method. By doing this it will produce result as shown below.

That's all.

If yo call setTheme(R.style.yourtheme); method after super.onCreate(savedInstanceState); method it will produce result as shown below.

Note: Themes are not recognize by nested PreferenceScreen. To apply theme to that nested PreferenceScreen you have to make an another PreferenceActivity for that nested PreferenceScreen and call setTheme(R.style.yourtheme); method there.




回答3:


Looking at the source of PreferenceScreen#showDialog(Bundle), we see that the dialog is created using the theme resource obtained via mContext.getThemeResId(), which is then used in a ContextThemeWrapper.

This can help us substantially, because all we have to do is override the getThemeResId() method in your Activity (which is hidden from the public API), to provide our custom theme, and the sub-PreferenceScreen now uses whatever custom theme resource we wanted!

/**
 * 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;
}

Note that because this method is annotated with @hide, we can't use the @Override annotation that would normally be used in this case; and we also can't call to the super.getThemeResId() method. If you really, really want to be able to conditionally override this and call through to the super implementation as a fallback, you'll have to use Reflection to get to the super implementation's method:

        try {
            ((Object) this).getClass().getMethod("getThemeResId").invoke(this);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }



回答4:


As all the other answers try to solve it using the java code, this is how I did it completely using xml and without declaring my own preference class.

First I copied the complete layout for a preference from here and changed all the "@+android:id/xyz" to "@android:id/xyz". Then in my styles file, I declared a new style as:

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

Now in the AppTheme, a new entry for preference:

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

Now for this new layout set all the styles you want. That's it.




回答5:


@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);
}


来源:https://stackoverflow.com/questions/10228482/how-to-apply-theme-to-preferencescreen-elements-of-a-preferencecategory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!