Android DarkMode: Value night не работает

Я разрабатываю в своем приложении функцию "День / ночь", поэтому я прочитал эти документы и приступил к разработке.

Он отлично работает со значением по умолчанию в Day или Night с методом deligate AppCompatDelegate.setDefaultNightMode(*).

Для настройки цвета ночной темы я создаю папку values-night и внутри создаю файл colors.xml, как показано ниже.

res -> values -> colors.xml
res -> values-night -> colors.xml

После того, как я помещаю этот цвет, но не применяю его в ночной теме! Очень странно, почему ночные цвета не всегда применяют свой ночной цвет по умолчанию? Я исследовал некоторые, но не могу найти решение.

Примечание. Повторное создание активности решило мою проблему, но я не хочу воссоздавать

Вот мой файл build.gradle

Заранее спасибо.

2 ответа

Попробуйте использовать код темного режима ниже, который я использую.

Шаг 1

Сначала создайте ночную папку в вашем файле ресурсов, как показано ниже (например, значения-ночь)

Шаг 2

Создайте XML-файл стилей, строк и цветов для ночного режима так же, как на изображении ниже, и добавьте цвет, строку и стиль ночного режима, которые вы хотите показать в своем приложении, когда был применен ночной режим.

Для лучшего взаимодействия с пользователем добавьте анимацию окон в свой стиль.

значения -> style.xml

<resources xmlns:tools="http://schemas.android.com/tools">

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="NoActionBarAppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/white</item>
        <item name="colorPrimaryDark">@color/white</item>
        <item name="colorAccent">@color/main_click_txt</item>
        <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
    </style>

    <!-- Add this theme where you change mode -->
    <style name="NoActionBarWithChangeTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/white</item>
        <item name="colorPrimaryDark">@color/white</item>
        <item name="colorAccent">@color/main_click_txt</item>
        <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
        <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
    </style>

    <!-- This will set the fade in animation on your change theme activity by default -->
    <style name="WindowAnimationTransition">
        <item name="android:windowEnterAnimation">@anim/fade_in</item>
        <item name="android:windowExitAnimation">@anim/fade_out</item>
    </style>

</resources>

значения-ночь -> style.xml

<!-- Base application theme. values-night.xml -->
<style name="NoActionBarAppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/white</item>
    <item name="colorPrimaryDark">@color/white</item>
    <item name="colorAccent">@color/main_click_txt</item>
    <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>

<!-- Add this theme where you change mode -->
<style name="NoActionBarWithChangeTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/white</item>
    <item name="colorPrimaryDark">@color/white</item>
    <item name="colorAccent">@color/main_click_txt</item>
    <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
    <item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>

<!-- This will set the fade in animation on your change activity by default -->
<style name="WindowAnimationTransition">
    <item name="android:windowEnterAnimation">@anim/fade_in</item>
    <item name="android:windowExitAnimation">@anim/fade_out</item>
</style>

fade_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator">
    <alpha
        android:duration="2000"
        android:fromAlpha="0.0"
        android:toAlpha="1.0">
    </alpha>
</set>

fade_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator">
    <alpha
        android:duration="2000"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" >
    </alpha>
</set>

Шаг 3

Добавьте приведенный ниже код на экран-заставку, если вы хотите установить ночной режим в соответствии с режимом устройства в первый раз при установке приложения.

@Override
protected void onCreate(Bundle savedInstanceState) {
    if (!CommonUtils.isToogleEnabled(SplashActivity.this)) {
        if (CommonUtils.isDarkMode(SplashActivity.this)) {
            CommonUtils.setIsNightModeEnabled(SplashActivity.this, true);
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        } else {
            CommonUtils.setIsNightModeEnabled(SplashActivity.this, false);
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }
    } else {
        if (CommonUtils.isNightModeEnabled(SplashActivity.this)) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }
    }
    super.onCreate(savedInstanceState);

    ...
    //your code
}

Шаг - 4

Добавьте этот код ниже во все свои действия

@Override
protected void onCreate(Bundle savedInstanceState) {
    if (CommonUtils.isNightModeEnabled(MainActivity.this)) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    } else {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
    }
    super.onCreate(savedInstanceState);

    ...
    //your code
}

Шаг - 5

Измените режим, используя приведенный ниже код

private WeakReference<Activity> mActivity;

binding.imgNightMode.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        mActivity = new WeakReference<Activity>(MainActivity.this);
        CommonUtils.setIsToogleEnabled(MainActivity.this, true);
        if (CommonUtils.isNightModeEnabled(MainActivity.this)) {
            CommonUtils.setIsNightModeEnabled(MainActivity.this, false);
            mActivity.get().recreate();
        } else {
            CommonUtils.setIsNightModeEnabled(MainActivity.this, true);
            mActivity.get().recreate();
        }
    }
});

Ниже приведены методы CommonUtils.

private static final String NIGHT_MODE = "NIGHT_MODE";
private static final String TOOGLE = "TOOGLE";

public static boolean isNightModeEnabled(Context context) {
    SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
    return mPrefs.getBoolean(NIGHT_MODE, false);
}

public static void setIsNightModeEnabled(Context context, boolean isNightModeEnabled) {
    SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
    SharedPreferences.Editor editor = mPrefs.edit();
    editor.putBoolean(NIGHT_MODE, isNightModeEnabled);
    editor.apply();
}

public static void setIsToogleEnabled(Context context, boolean isToogleEnabled) {
    SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
    SharedPreferences.Editor editor = mPrefs.edit();
    editor.putBoolean(TOOGLE, isToogleEnabled);
    editor.apply();
}

public static boolean isToogleEnabled(Context context) {
    SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
    return mPrefs.getBoolean(TOOGLE, false);
}

public static boolean isDarkMode(Activity activity) {
    return (activity.getResources().getConfiguration()
            .uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}

Я надеюсь это тебе поможет!

Благодарю вас.

Измените зависимость appcompat с 1.1.0 на 1.0.0. Существует некоторая проблема с обновлением ресурса в 1.1.0. У меня этот трюк сработал.

 implementation 'androidx.appcompat:appcompat:1.1.0'//Remove 
 implementation 'androidx.appcompat:appcompat:1.0.0' // Add

Надеюсь, что это поможет вам!!

Другие вопросы по тегам