diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 7164edf195c4..196cbcf3c1c1 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2465,6 +2465,7 @@ public final class com/facebook/react/modules/appearance/AppearanceModule : com/ public fun addListener (Ljava/lang/String;)V public final fun emitAppearanceChanged (Ljava/lang/String;)V public fun getColorScheme ()Ljava/lang/String; + public fun invalidate ()V public final fun invalidatePlatformColorCache ()V public final fun onConfigurationChanged (Landroid/content/Context;)V public fun removeListeners (D)V @@ -2475,7 +2476,14 @@ public final class com/facebook/react/modules/appearance/AppearanceModule$Compan } public abstract interface class com/facebook/react/modules/appearance/AppearanceModule$OverrideColorScheme { + public abstract fun addSchemeChangeListener (Lkotlin/jvm/functions/Function0;)V public abstract fun getScheme ()Ljava/lang/String; + public abstract fun removeSchemeChangeListener (Lkotlin/jvm/functions/Function0;)V +} + +public final class com/facebook/react/modules/appearance/AppearanceModule$OverrideColorScheme$DefaultImpls { + public static fun addSchemeChangeListener (Lcom/facebook/react/modules/appearance/AppearanceModule$OverrideColorScheme;Lkotlin/jvm/functions/Function0;)V + public static fun removeSchemeChangeListener (Lcom/facebook/react/modules/appearance/AppearanceModule$OverrideColorScheme;Lkotlin/jvm/functions/Function0;)V } public abstract interface class com/facebook/react/modules/appregistry/AppRegistry : com/facebook/react/bridge/JavaScriptModule { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt index aa89f287cc29..443baea4528f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt @@ -28,13 +28,42 @@ constructor( private var lastEmittedColorScheme: String? = null + private val schemeChangeListener: () -> Unit = { + val activity = reactApplicationContext.getCurrentActivity() + onConfigurationChanged(activity ?: reactApplicationContext) + } + + init { + // Register as a listener for color scheme changes if override is provided + overrideColorScheme?.addSchemeChangeListener(schemeChangeListener) + } + /** Optional override to the current color scheme */ - public fun interface OverrideColorScheme { + public interface OverrideColorScheme { /** * Color scheme will use the return value instead of the current system configuration. Available * scheme: {light, dark} */ public fun getScheme(): String + + /** + * Register a listener to be notified when the color scheme changes. The listener will be + * invoked whenever the underlying theme preference changes. + * + * Default implementation does nothing. Override this method if you want to support dynamic + * color scheme updates. + */ + public fun addSchemeChangeListener(listener: () -> Unit) { + // no-op + } + + /** + * Unregisters a previously added color scheme change listener. Default implementation is a + * no-op; override to remove the listener from your source. + */ + public fun removeSchemeChangeListener(listener: () -> Unit) { + // no-op + } } private fun colorSchemeForCurrentConfiguration(context: Context): String { @@ -98,6 +127,12 @@ constructor( Companion.invalidatePlatformColorCache?.run() } + public override fun invalidate() { + overrideColorScheme?.removeSchemeChangeListener(schemeChangeListener) + invalidatePlatformColorCache() + super.invalidate() + } + public companion object { public const val NAME: String = NativeAppearanceSpec.NAME private const val APPEARANCE_CHANGED_EVENT_NAME = "appearanceChanged"