11

I've just migrated from support library to AndroidX. Most of my code works fine but suddenly my custom preference theme stoped working.

My app has mostly dark background so I set the text color to white variants but in my settings the background color is light so the title and subtitle of the preferences should be dark variant. During my attempts to customize my preference fragment I used the solution from this -> How to style PreferenceFragmentCompat Sadly, after migrating from support library to AndroidX this solution stopped working.

These are my actual dependencies afhter the migration:

implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
implementation 'com.google.android.material:material:1.1.0-alpha02'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
implementation 'androidx.preference:preference:1.1.0-alpha02'
implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha01'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'

This is my actual theme that used to work.

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- General theme colors -->
    <item name="colorPrimary">@color/appColorPrimary</item>
    <item name="colorPrimaryDark">@color/appColorPrimaryDark</item>
    <item name="colorAccent">@color/appColorAccent</item>

    <!-- Text Appearance styles -->
    <item name="android:textViewStyle">@style/TextViewStyle.Serif</item>
    <item name="android:textColorPrimary">@color/textColorPrimary</item>
    <item name="android:textColorSecondary">@color/textColorSecondary</item>
    <item name="android:textColorTertiary">@color/textColorTertiary</item>
    <item name="android:textColorLinkInverse">@color/textColorLinkInverse</item>

<!--For the SearchView cursor color-->
    <item name="colorControlActivated">@color/white</item>

<!--Custom styles and themes -->
    <item name="preferenceTheme">@style/AppTheme.PreferenceTheme</item>
    <item name="actionOverflowMenuStyle">@style/AppTheme.OverflowMenu</item>
    <item name="alertDialogTheme">@style/AlertDialogStyle</item>
    <!-- Custom attributes defined in attrs.xml -->
    <item name="dividerColor">@color/dividerColor</item>
</style>


<!--Preference screen theme-->
<style name="AppTheme.PreferenceTheme" parent="PreferenceThemeOverlay.v14.Material">
    <!--Overriding textColor primary/secondary from main theme-->
    <item name="android:textColorPrimary">@color/textColorPrimaryInverse</item>
    <item name="android:textColorSecondary">@color/textColorSecondaryInverse</item>
    <item name="android:colorControlActivated">@color/appColorPrimary</item>
</style>

Is there any solution for this new situation ?

mbojec
  • 163
  • 1
  • 7
  • Your preference theme's `parent` should now be just `PreferenceThemeOverlay`, instead of `PreferenceThemeOverlay.v14.Material`. – Mike M. Jan 08 '19 at 20:38
  • I've tried this solution but still it uses the main theme colors instead of those provided in my custom AppTheme.PreferenceTheme :\ – mbojec Jan 08 '19 at 20:49
  • Is your preference.xml referencing anything from the old version, like `>`? After migrating AndroidX, I changed my preference.xml's tags like this: `>`. I implemented my custom preference theme exactly like you and it works well. – WasabiTea Jan 08 '19 at 20:58
  • No, during the migration it didn't changed, it stile like this: – mbojec Jan 08 '19 at 21:02
  • Any news on this topic? Same issue on my side. My app is almost black and black preference titles on black background doesn't work well. The only solution working for me, is to override all available preference layouts using my custom text color styling. The solution to override textColorPrimary and textColorSecondary stopped working after migrating to androidx.preference – user3749883 Aug 27 '20 at 19:31

1 Answers1

2

I'm adding this here so it may help someone in the future

If you migrate from Support Library to AndroidX, everything should work the same if you use first versions of Preference library. For example:

implementation 'androidx.preference:preference:1.0.0'

If you try to update to the latest version, you may face issues like this. I'm was investigating this issue and I found the reason. In the latest versions of PreferenceFragmentCompat, we can find this code:

// Source code of version 1.1.1
public abstract class PreferenceFragmentCompat extends Fragment implements

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        ...
        getActivity().getTheme().applyStyle(theme, false);
    }
}

As we can see, second parameter of applyStyle is false. Checking the javadoc of that method, we can see:

 * @param resId The resource ID of a style resource from which to
 *              obtain attribute values.
 * @param force If true, values in the style resource will always be
 *              used in the theme; otherwise, they will only be used
 *              if not already defined in the theme.
 */
public void applyStyle(int resId, boolean force)

So, the attributes defined in AppTheme.PreferenceTheme will only take effect if they WERE NOT DEFINED early in the AppTheme itself. In the code above, we can see that some properties are defined in both themes.. So, they won't take affect in the Preference screen because AppTheme will be prioritized.

In the first version, 1.0.0, the theme is applied in a different way:

// Source code of version 1.0.0
public abstract class PreferenceFragmentCompat extends Fragment implements

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        ...
        mStyledContext = new ContextThemeWrapper(getActivity(), theme);
        mPreferenceManager = new PreferenceManager(mStyledContext);
    }
}

So, in other words: If you migrated from Support library and you Preference screen theme broke, try to avoid the latest version available and use version 1.0.0, for example.

OP mentioned in the description that he used version:

implementation 'androidx.preference:preference:1.1.0-alpha02'

This issue is blocking me from migrate to latest versions because I don't want to re-work whole app's theme just to update the settings screen.

guipivoto
  • 18,327
  • 9
  • 60
  • 75