I have tried to implement gradient view via native UI component RN approach (Android only for now). Everything seems fine except one: @ReactProp
setters doesn't called and I don't even imagine why :(
Details:
- RN version: 0.60.4
Here is the code (ViewManager, View, RN component):
ViewManager:
package com.bastionpassmobile.splashgradient;import com.facebook.react.uimanager.SimpleViewManager;import com.facebook.react.uimanager.ThemedReactContext;/** * View manager for splash background gradient view. */public class SplashGradientViewManager extends SimpleViewManager<SplashGradientView> { public static final String REACT_CLASS = "RCTSplashGradientView"; @Override public String getName() { return REACT_CLASS; } @Override protected SplashGradientView createViewInstance(ThemedReactContext reactContext) { return new SplashGradientView(reactContext); }}
View:
package com.bastionpassmobile.splashgradient;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RadialGradient;import android.graphics.Shader;import com.facebook.react.bridge.ReadableArray;import com.facebook.react.uimanager.annotations.ReactProp;import com.facebook.react.views.view.ReactViewGroup;/** * View serves as background gradient for splash screen. */public class SplashGradientView extends ReactViewGroup { float radius; int[] colors; int width; int height; public SplashGradientView(Context context) { super(context); radius = 0; colors = new int[0]; width = 0; height = 0; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (radius > 0) { RadialGradient radialGradient = new RadialGradient(width / 2, height / 2, radius, colors, null, Shader.TileMode.CLAMP); Paint paint = new Paint(); paint.setShader(radialGradient); canvas.drawPaint(paint); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); width = w; height = h; } /** * Sets gradient radius. * @param {SplashGradientView} view * @param {float} value */ @ReactProp(name = "radius") public void setRadius(SplashGradientView view, float value) { radius = value; view.invalidate(); } /** * Sets gradient colors. * @param {SplashGradientView} view * @param {ReadableArray} value */ @ReactProp(name = "colors") public void setColors(SplashGradientView view, ReadableArray value) { colors = new int[value.size()]; for (int i = 0; i < value.size(); i++) { colors[i] = Color.parseColor(value.getString(i)); } view.invalidate(); }}
RN component:
import * as React from "react";import { requireNativeComponent, StyleProp, ViewStyle } from "react-native";interface CRadialGradientProps { style?: StyleProp<ViewStyle>; radius: number; /** * Each element of the array should be defined as hex color representation. */ colors: string[];}const RadialGradientView = requireNativeComponent("RCTSplashGradientView");/** * Represents radial gradient view. */export class CRadialGradient extends React.Component<CRadialGradientProps> { render() { return (<RadialGradientView {...this.props}/> ); }}
And render of course:
render() {<CRadialGradient radius={600} colors={["#353946", "#1E212C"]} /> }