Skip to content

Commit

Permalink
[Color] Update DynamicColors util to applyStyle() on window decorView…
Browse files Browse the repository at this point in the history
… theme as well to fix potential ContextMenu issue

PiperOrigin-RevId: 426416360
  • Loading branch information
dsn5ft authored and pekingme committed Feb 4, 2022
1 parent 8b9be72 commit f6c8fa5
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions lib/java/com/google/android/material/color/DynamicColors.java
Expand Up @@ -22,12 +22,15 @@
import android.app.Application;
import android.app.Application.ActivityLifecycleCallbacks;
import android.content.Context;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.Window;
import androidx.annotation.ChecksSdkIntAtLeast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -231,8 +234,7 @@ private static void applyIfAvailable(
theme = getDefaultThemeOverlay(activity);
}
if (theme != 0 && precondition.shouldApplyDynamicColors(activity, theme)) {
// Use applyStyle() instead of setTheme() due to Force Dark issue.
activity.getTheme().applyStyle(theme, /* force= */ true);
applyDynamicColorThemeOverlay(activity, theme);
}
}

Expand Down Expand Up @@ -297,6 +299,33 @@ private static int getDefaultThemeOverlay(@NonNull Context context) {
return theme;
}

private static void applyDynamicColorThemeOverlay(Activity activity, @StyleRes int theme) {
// Use applyStyle() instead of setTheme() due to Force Dark issue.
activity.getTheme().applyStyle(theme, /* force= */ true);

// Make sure theme is applied to the Window decorView similar to Activity#setTheme, to ensure
// that the dynamic colors will be applied to things like ContextMenu using the DecorContext.
Theme windowDecorViewTheme = getWindowDecorViewTheme(activity);
if (windowDecorViewTheme != null) {
windowDecorViewTheme.applyStyle(theme, /* force= */ true);
}
}

@Nullable
private static Theme getWindowDecorViewTheme(@NonNull Activity activity) {
Window window = activity.getWindow();
if (window != null) {
View decorView = window.getDecorView();
if (decorView != null) {
Context context = decorView.getContext();
if (context != null) {
return context.getTheme();
}
}
}
return null;
}

/**
* The interface that provides a precondition to decide if dynamic colors should be applied.
*/
Expand Down

0 comments on commit f6c8fa5

Please sign in to comment.