如何在新的AndroidX库中自定义首选项屏幕

时间:2019-01-08 20:32:09

标签: android

我刚刚从支持库迁移到AndroidX。我的大多数代码都能正常工作,但突然我的自定义首选项主题停止工作。

我的应用程序大多是深色背景,因此我将文本颜色设置为白色变体,但是在我的设置中,背景色是浅色,因此首选项的标题和副标题应该是深色变体。在尝试自定义首选项片段的过程中,我使用了此解决方案-> How to style PreferenceFragmentCompat,可悲的是,从支持库迁移到AndroidX后,该解决方案停止了工作。

这些是我迁移后的实际依赖关系:

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'

这是我曾经工作过的实际主题。

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

这种新情况有解决方案吗?

1 个答案:

答案 0 :(得分:0)

我在此处添加此内容,以便将来对某人有所帮助

如果您从支持库迁移到 AndroidX,如果您使用首个版本的首选项库,一切都应该相同。例如:

implementation 'androidx.preference:preference:1.0.0'

如果您尝试更新到最新版本,您可能会遇到这样的问题。我正在调查这个问题,我找到了原因。 在最新版本的 PreferenceFragmentCompat 中,我们可以找到以下代码:

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

如我们所见,applyStyle 的第二个参数是 false。检查该方法的javadoc,我们可以看到:

 * @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)

因此,AppTheme.PreferenceTheme 中定义的属性只有在 AppTheme 本身早期未定义时才会生效。在上面的代码中,我们可以看到在两个主题中都定义了一些属性。因此,它们不会在 Preference 屏幕中生效,因为 AppTheme 将被优先考虑。

在第一个版本 1.0.0 中,主题以不同的方式应用:

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

因此,换句话说:如果您从支持库迁移并且您的首选项屏幕主题损坏,请尽量避免使用最新版本并使用版本 1.0.0,例如。

描述中提到的OP他使用的版本:

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

这个问题阻止我迁移到最新版本,因为我不想为了更新设置屏幕而重新设计整个应用的主题。