Adaptação de comutação do modo diurno e noturno do Android e a solução para a destruição e reinicialização da Atividade causada por ele

Índice

1. Para alternar entre o modo branco e noturno, destrua e reinicie a Atividade para resolver:

2. Adaptação ao modo escuro

 1. Adicione dependências:

  2. Copie o seguinte método de classe de ferramentas e use-o diretamente:

3. Adaptação de recursos:

 4. Callback de adaptação:

5. Precauções para mudar o modo noturno branco:


1. Para alternar entre o modo branco e noturno, destrua e reinicie a Atividade para resolver:

        Quando o modo noturno branco for ativado, a atividade será destruída e recarregada. O Google espera que recarregar a atividade possa atualizar a interface do usuário da página, mas meu aplicativo não está adaptado para o modo escuro, então a experiência do usuário é muito ruim. A solução é :

Adicione ou anexe o atributo android:configChanges="uiMode" a Activiyty em AndroidManifest.xml :

 Detalhes do parâmetro configChanges:

 

2. Adaptação ao modo escuro

 1. Adicione dependências:

api 'com.android.support:appcompat-v7:24.1.1' 或者更高版本
或使用androidx的依赖都可以

  2. Copie o seguinte método de classe de ferramentas e use-o diretamente:

/**
 * 暗黑模式适配工具类
 */
public class DarkModeUtils {

    public static final String KEY_MODE = "white_night_mode_sp";

    /**
     * 在 Application 的 onCreate() 方法中调用
     */
    public static void init(Application application) {
        int nightMode = getNightModel(application);
        AppCompatDelegate.setDefaultNightMode(nightMode);
    }

    /**
     * 应用夜间模式
     */
    public static void applyNightMode(Context context) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        setNightModel(context, AppCompatDelegate.MODE_NIGHT_YES);
    }

    /**
     * 应用日间模式
     */
    public static void applyDayMode(Context context) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        setNightModel(context, AppCompatDelegate.MODE_NIGHT_NO);
    }

    /**
     * 跟随系统主题时需要动态切换
     */
    public static void applySystemMode(Context context) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
        setNightModel(context, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
    }

    /**
     * 判断App当前是否处于暗黑模式状态
     */
    public static boolean isDarkMode(Context context) {
        int nightMode = getNightModel(context);
        if (nightMode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
            int applicationUiMode = context.getResources().getConfiguration().uiMode;
            int systemMode = applicationUiMode & Configuration.UI_MODE_NIGHT_MASK;
            return systemMode == Configuration.UI_MODE_NIGHT_YES;
        } else {
            return nightMode == AppCompatDelegate.MODE_NIGHT_YES;
        }
    }

    private static int getNightModel(Context context) {
        SharedPreferences sp = context.getSharedPreferences(KEY_MODE, Context.MODE_PRIVATE);
        return sp.getInt(KEY_MODE, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
    }

    public static void setNightModel(Context context, int nightMode) {
        SharedPreferences sp = context.getSharedPreferences(KEY_MODE, Context.MODE_PRIVATE);
        sp.edit().putInt(KEY_MODE, nightMode).apply();
    }

}

3. Adaptação de recursos:

       Crie uma pasta de modo escuro para fotos e cores, e o sistema usará automaticamente os recursos dessa pasta ao alternar para o modo escuro:

 4. Callback de adaptação:

Se o atributo android:configChanges="uiMode" for adicionado ou adicionado  , o onConfigurationChanged() da Activity será chamado de volta depois que o modo for trocado . Recomenda-se reescrever este método em BaseActivity e fazer as adaptações correspondentes nele.

Você pode chamar o método DarkModeUtils.isDarkMode(this) na classe de ferramenta acima para determinar se está no modo escuro. Você também pode chamar o método na classe de ferramenta para alternar o modo noturno branco do aplicativo. As observações são as seguintes:

5. Precauções para mudar o modo noturno branco:

(1) Chame DarkModeUtils.init(this) no método onCreate() de Application para inicializar a classe de ferramenta;

(2) Chame o método DarkModeUtils.applySystemMode(this) para alternar entre os modos branco e noturno do sistema adaptativo;

(3) Se a dependência de androidx for usada, ela pode ser chamada diretamente.

(4) Se você usar dependências de suporte, precisará chamar manualmente o método recreate() da Activity para reconstruir a página ou fazer diferentes adaptações para todas as Views na página.

Exemplo de chamada direta do método recreate() para reconstruir a página:

 Exemplo de configuração do modo branco e noturno para cada Visualização na página:

(5) Veja o código fonte abaixo para razões específicas:

versão androidx:

/**
     * Sets the default night mode. This is the default value used for all components, but can
     * be overridden locally via {@link #setLocalNightMode(int)}.
     *
     * <p>This is the primary method to control the DayNight functionality, since it allows
     * the delegates to avoid unnecessary recreations when possible.</p>
     *
     * <p>If this method is called after any host components with attached
     * {@link AppCompatDelegate}s have been 'started', a {@code uiMode} configuration change
     * will occur in each. This may result in those components being recreated, depending
     * on their manifest configuration.</p>
     *
     * <p>Defaults to {@link #MODE_NIGHT_FOLLOW_SYSTEM}.</p>
     *
     * @see #setLocalNightMode(int)
     * @see #getDefaultNightMode()
     */
    public static void setDefaultNightMode(@NightMode int mode) {
        switch (mode) {
            case MODE_NIGHT_NO:
            case MODE_NIGHT_YES:
            case MODE_NIGHT_FOLLOW_SYSTEM:
            case MODE_NIGHT_AUTO_TIME:
            case MODE_NIGHT_AUTO_BATTERY:
                if (sDefaultNightMode != mode) {
                    sDefaultNightMode = mode;
                    applyDayNightToActiveDelegates();
                }
                break;
            default:
                Log.d(TAG, "setDefaultNightMode() called with an unknown mode");
                break;
        }
    }

versão de suporte:

public static void setDefaultNightMode(int mode) {
        switch(mode) {
        case -1:
        case 0:
        case 1:
        case 2:
            sDefaultNightMode = mode;
            break;
        default:
            Log.d("AppCompatDelegate", "setDefaultNightMode() called with an unknown mode");
        }
    }

Após a comparação, pode-se descobrir que, depois que o androidx mudou para o modo escuro, ele chamou ativamente o método applyDayNightToActiveDelegates() para reconstruir a atividade. Mas não há suporte, apenas atribuição. Portanto, o uso da versão de suporte precisa chamar o método recreate() da Activity a ser reconstruída.

Acho que você gosta

Origin blog.csdn.net/zhao8856234/article/details/126578124
Recomendado
Clasificación