mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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  Reviewed By: mdvacca Differential Revision: D21125479 Pulled By: shergin fbshipit-source-id: 14dcc023977d7a9d304fabcd3c90bcf34482f137
This commit is contained in:
committed by
Facebook GitHub Bot
parent
e96f1e1d83
commit
cfa4260598
@@ -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<{|
|
||||
/**
|
||||
|
||||
@@ -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 (
|
||||
<View style={styles.wrapper}>
|
||||
<View style={[styles.box, styles.elevation1]} />
|
||||
<View style={[styles.box, styles.elevation2]} />
|
||||
<View style={[styles.box, styles.elevation3]} />
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Fractional elevation',
|
||||
description: 'elevation: 0.1, 0.5, 1.5',
|
||||
platform: 'android',
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.wrapper}>
|
||||
<View style={[styles.box, {elevation: 0.1}]} />
|
||||
<View style={[styles.box, {elevation: 0.5}]} />
|
||||
<View style={[styles.box, {elevation: 1.5}]} />
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Colored shadow',
|
||||
description: "shadowColor: 'red', 'blue', '#00FF0080'",
|
||||
platform: 'android',
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.wrapper}>
|
||||
<View style={[styles.box, styles.elevation1, styles.shadowColor1]} />
|
||||
<View style={[styles.box, styles.elevation2, styles.shadowColor2]} />
|
||||
<View style={[styles.box, styles.elevation3, styles.shadowColor3]} />
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Shaped shadow',
|
||||
description: 'borderRadius: 50',
|
||||
platform: 'android',
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.wrapper}>
|
||||
<View style={[styles.box, styles.elevation1, styles.shadowShaped]} />
|
||||
<View style={[styles.box, styles.elevation2, styles.shadowShaped]} />
|
||||
<View style={[styles.box, styles.elevation3, styles.shadowShaped]} />
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Borders',
|
||||
description: 'borderWidth: 5',
|
||||
platform: 'android',
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.wrapper}>
|
||||
<View style={[styles.box, styles.elevation1, styles.border]} />
|
||||
<View style={[styles.box, styles.elevation2, styles.border]} />
|
||||
<View style={[styles.box, styles.elevation3, styles.border]} />
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -144,6 +144,10 @@ const APIExamples: Array<RNTesterExample> = [
|
||||
key: 'BorderExample',
|
||||
module: require('../examples/Border/BorderExample'),
|
||||
},
|
||||
{
|
||||
key: 'BoxShadowExample',
|
||||
module: require('../examples/BoxShadow/BoxShadowExample'),
|
||||
},
|
||||
{
|
||||
key: 'ClipboardExample',
|
||||
module: require('../examples/Clipboard/ClipboardExample'),
|
||||
|
||||
@@ -95,6 +95,15 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
||||
ViewCompat.setElevation(view, PixelUtil.toPixelFromDIP(elevation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ReactProp(name = ViewProps.SHADOW_COLOR, defaultInt = Color.BLACK, customType = "Color")
|
||||
public void setShadowColor(@NonNull T view, int shadowColor) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
view.setOutlineAmbientShadowColor(shadowColor);
|
||||
view.setOutlineSpotShadowColor(shadowColor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ReactProp(name = ViewProps.Z_INDEX)
|
||||
public void setZIndex(@NonNull T view, float zIndex) {
|
||||
|
||||
@@ -54,6 +54,9 @@ public abstract class BaseViewManagerAdapter<T extends View>
|
||||
@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) {}
|
||||
|
||||
@@ -74,6 +74,10 @@ public abstract class BaseViewManagerDelegate<T extends View, U extends BaseView
|
||||
case ViewProps.ELEVATION:
|
||||
mViewManager.setElevation(view, value == null ? 0.0f : ((Double) value).floatValue());
|
||||
break;
|
||||
case ViewProps.SHADOW_COLOR:
|
||||
mViewManager.setShadowColor(
|
||||
view, value == null ? 0 : ColorPropConverter.getColor(value, view.getContext()));
|
||||
break;
|
||||
case ViewProps.IMPORTANT_FOR_ACCESSIBILITY:
|
||||
mViewManager.setImportantForAccessibility(view, (String) value);
|
||||
break;
|
||||
|
||||
@@ -43,6 +43,8 @@ public interface BaseViewManagerInterface<T extends View> {
|
||||
|
||||
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);
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user