2016-05-15 7 views
4

AppCompatDelegate.MODE_NIGHT_AUTO aktualisiert meine vorhandene Aktivität nicht und ich bin nicht sicher warum.AppCompat MODE_NIGHT_AUTO funktioniert nicht

Ich erlaube dynamisch dem Benutzer, Nachtmodus zu ändern. Wenn der Benutzer den Modus auf Auto ändert gesetzt ich den Standard-Nachtmodus dann die Aktivität neu:

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO); 
recreate(); 

Wenn ich MODE_NIGHT_YES oder MODE_NIGHT_NO ändern, es funktioniert wie erwartet. Wenn ich zu MODE_NIGHT_AUTO wechsle, geht es zum richtigen Dark/Light-Thema, aber dann wird die Aktivität nach dem Übergang von Tag zu Nacht nicht aktualisiert. Es ist etwas nervig, das zu testen, weil ich auf Sonnenaufgang/Sonnenuntergang warten muss (BEARBEITEN: Ich kann die Zeit auf dem Gerät manuell ändern, anstatt warten zu müssen ... solange die Standortgenehmigung nicht verwendet wird).

Muss ich eine manuelle Überprüfung für den Nachtmodus-Flag in onresume durchführen und Ressourcen für vorhandene Aktivitäten manuell aktualisieren, oder mache ich etwas falsch? Wenn ich das Gerät rotiere und die Aktivität nach Sonnenuntergang neu erstellt wird, wird das dunkle Thema korrekt aufgenommen, aber vor der Drehung wird immer noch das helle Thema angezeigt.

Unterstützung lib 23.4.0, Android-Version 6.0.

+0

Es könnte argumentiert werden, dass es ein Fehler ist. Es ist nicht zu Unrecht zu erwarten, dass der Wechsel von Tag zu Nacht (oder umgekehrt) eine Konfigurationsänderung auslösen sollte, die Ihre Aktivitäten automatisch neu erstellen würde. Zumindest wäre es schön, sich dafür zu entscheiden. Ich denke, es lohnt sich, in AOSP Bug Tracker zu berichten. –

Antwort

1

Falls jemand wissen will, was ich tat dies (nicht sicher, ob es der richtige Weg ist es aber zu tun) zu lösen:

private int mCurrentNightMode; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    mCurrentNightMode = getCurrentNightMode(); 
} 

@Override 
protected void onPostResume() { 
    super.onPostResume(); 

    if (hasNightModeChanged()) { 
     delayedRecreate(); 
    } 

} 

private void delayedRecreate() { 
    Handler handler = new Handler(); 
    handler.postDelayed(this::recreate, 1); 
} 

private boolean hasNightModeChanged() { 
    getDelegate().applyDayNight(); 
    return mCurrentNightMode != getCurrentNightMode(); 
} 

private int getCurrentNightMode() { 
    return getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; 
} 
+0

Warum müssen Sie den Aufruf von 'recreate()' verzögern? –

+1

@ MarcinKoziński - Sie können recreate() in resume/postresume nicht ohne Abstürze aufrufen (kann sich nicht an die genaue Ausnahme erinnern). – timothyjc

+0

Vielen Dank für diese Lösung. Bis jetzt habe ich keine Abstürze oder Ned gesehen, um das recreate() zu verzögern. –

1

Es ist in AppCompat 24.2.0 behoben. Revision history Listen dies als „Verhaltensänderung“ für 24.2.0:

Wenn Sie die Tag/Nacht-Funktionalität appcompat Bibliothek, das System nun automatisch Ihre Aktivität neu erstellt, wenn der Tag/Nacht-Modus Änderungen (entweder weil der Uhrzeit oder aufgrund eines Anrufs zu AppCompatDelegate.setLocalNightMode()).

+0

Prost! Das habe ich auch bemerkt :) – timothyjc

+0

Dies funktioniert für die aktuelle Aktivität. Wenn jedoch auf die Aktivitäten zurückgegriffen wird, wird nichts neu erstellt. Wenn Sie so etwas wie einen ViewPager haben, der neue Fragmente erstellt, erhalten Sie plötzlich eine Mischung aus Tag und Nacht. https://Stackoverflow.com/a/37631109/467650 löste das für mich. –

Verwandte Themen