From cfa42605989eee5a9de42bdb1259fb7f4d9451fb Mon Sep 17 00:00:00 2001 From: Hein Rutjes Date: Tue, 7 Jul 2020 23:30:10 -0700 Subject: [PATCH] Add support for shadowColor on Android (API >= 28) (#28650) Summary: This PR adds support for the `shadowColor` style on Android. This is possible as of Android P using the `setOutlineAmbientShadowColor` and `setOutlineSpotShadowColor` View methods. The actual rendered color is a multiplication of the color-alpha, shadow-effect and elevation-value. ## Changelog `[Android] [Added] - Add support for shadowColor on API level >= 28` Pull Request resolved: https://github.com/facebook/react-native/pull/28650 Test Plan: - Only execute code on Android P - Added Android `BoxShadow` tests to RNTester app ![image](https://user-images.githubusercontent.com/6184593/79457137-fe627c80-7fef-11ea-8e88-3d9423a4f264.png) Reviewed By: mdvacca Differential Revision: D21125479 Pulled By: shergin fbshipit-source-id: 14dcc023977d7a9d304fabcd3c90bcf34482f137 --- Libraries/StyleSheet/StyleSheetTypes.js | 5 +- .../js/examples/BoxShadow/BoxShadowExample.js | 94 +++++++++++++++++++ RNTester/js/utils/RNTesterList.android.js | 4 + .../react/uimanager/BaseViewManager.java | 9 ++ .../uimanager/BaseViewManagerAdapter.java | 3 + .../uimanager/BaseViewManagerDelegate.java | 4 + .../uimanager/BaseViewManagerInterface.java | 2 + .../facebook/react/uimanager/ViewProps.java | 1 + 8 files changed, 120 insertions(+), 2 deletions(-) diff --git a/Libraries/StyleSheet/StyleSheetTypes.js b/Libraries/StyleSheet/StyleSheetTypes.js index b2d596a14df..d9272898448 100644 --- a/Libraries/StyleSheet/StyleSheetTypes.js +++ b/Libraries/StyleSheet/StyleSheetTypes.js @@ -522,8 +522,9 @@ type ____TransformStyle_Internal = $ReadOnly<{| * Because they are dynamically generated, they may cause performance regressions. Static * shadow image asset may be a better way to go for optimal performance. * - * These properties are iOS only - for similar functionality on Android, use the [`elevation` - * property](docs/viewstyleproptypes.html#elevation). + * Shadow-related properties are not fully supported on Android. + * To add a drop shadow to a view use the [`elevation` property](docs/viewstyleproptypes.html#elevation) (Android 5.0+). + * To customize the color use the [`shadowColor` property](docs/shadow-props.html#shadowColor) (Android 9.0+). */ export type ____ShadowStyle_Internal = $ReadOnly<{| /** diff --git a/RNTester/js/examples/BoxShadow/BoxShadowExample.js b/RNTester/js/examples/BoxShadow/BoxShadowExample.js index 5801cf3f5ad..429fb0873c5 100644 --- a/RNTester/js/examples/BoxShadow/BoxShadowExample.js +++ b/RNTester/js/examples/BoxShadow/BoxShadowExample.js @@ -46,6 +46,29 @@ const styles = StyleSheet.create({ margin: 8, backgroundColor: 'red', }, + + elevation1: { + elevation: 1, + }, + elevation2: { + elevation: 3, + }, + elevation3: { + elevation: 10, + }, + shadowColor1: { + shadowColor: 'red', + }, + shadowColor2: { + shadowColor: 'blue', + }, + shadowColor3: { + shadowColor: '#00FF0080', + }, + border: { + borderWidth: 5, + borderColor: '#EEE', + }, }); exports.title = 'Box Shadow'; @@ -97,4 +120,75 @@ exports.examples = [ ); }, }, + + { + title: 'Basic elevation', + description: 'elevation: 1, 3, 6', + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, + { + title: 'Fractional elevation', + description: 'elevation: 0.1, 0.5, 1.5', + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, + { + title: 'Colored shadow', + description: "shadowColor: 'red', 'blue', '#00FF0080'", + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, + { + title: 'Shaped shadow', + description: 'borderRadius: 50', + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, + { + title: 'Borders', + description: 'borderWidth: 5', + platform: 'android', + render() { + return ( + + + + + + ); + }, + }, ]; diff --git a/RNTester/js/utils/RNTesterList.android.js b/RNTester/js/utils/RNTesterList.android.js index 66962af5154..0e01adf9f0c 100644 --- a/RNTester/js/utils/RNTesterList.android.js +++ b/RNTester/js/utils/RNTesterList.android.js @@ -144,6 +144,10 @@ const APIExamples: Array = [ key: 'BorderExample', module: require('../examples/Border/BorderExample'), }, + { + key: 'BoxShadowExample', + module: require('../examples/BoxShadow/BoxShadowExample'), + }, { key: 'ClipboardExample', module: require('../examples/Clipboard/ClipboardExample'), diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java index ef39975d493..2028bdb6082 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java @@ -95,6 +95,15 @@ public abstract class BaseViewManager= Build.VERSION_CODES.P) { + view.setOutlineAmbientShadowColor(shadowColor); + view.setOutlineSpotShadowColor(shadowColor); + } + } + @Override @ReactProp(name = ViewProps.Z_INDEX) public void setZIndex(@NonNull T view, float zIndex) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java index 6af559a15c9..c0e21dece66 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java @@ -54,6 +54,9 @@ public abstract class BaseViewManagerAdapter @Override public void setElevation(@NonNull T view, float elevation) {} + @Override + public void setShadowColor(@NonNull T view, int shadowColor) {} + @Override public void setImportantForAccessibility( @NonNull T view, @Nullable String importantForAccessibility) {} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java index f430398bacf..1598b578877 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java @@ -74,6 +74,10 @@ public abstract class BaseViewManagerDelegate { void setElevation(T view, float elevation); + void setShadowColor(T view, int shadowColor); + void setImportantForAccessibility(T view, @Nullable String importantForAccessibility); void setNativeId(T view, @Nullable String nativeId); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java index fcb4d2bb4f1..ac780e8bb4f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java @@ -140,6 +140,7 @@ public class ViewProps { public static final String TRANSFORM = "transform"; public static final String ELEVATION = "elevation"; + public static final String SHADOW_COLOR = "shadowColor"; public static final String Z_INDEX = "zIndex"; public static final String RENDER_TO_HARDWARE_TEXTURE = "renderToHardwareTextureAndroid"; public static final String ACCESSIBILITY_LABEL = "accessibilityLabel";