diff --git a/android/build.gradle b/android/build.gradle
index c3fa67ee..d16e2e1b 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -138,5 +138,5 @@ dependencies {
implementation "com.facebook.react:react-native:+"
// From node_modules
- implementation 'com.github.Dimezis:BlurView:version-2.0.3'
+ implementation 'com.github.Dimezis:BlurView:version-2.0.4'
}
diff --git a/android/src/main/java/com/reactnativecommunity/blurview/BlurViewManagerImpl.java b/android/src/main/java/com/reactnativecommunity/blurview/BlurViewManagerImpl.java
deleted file mode 100644
index 44443134..00000000
--- a/android/src/main/java/com/reactnativecommunity/blurview/BlurViewManagerImpl.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.reactnativecommunity.blurview;
-
-import android.view.View;
-import com.facebook.react.uimanager.ThemedReactContext;
-
-import eightbitlab.com.blurview.BlurView;
-
-import java.util.Objects;
-import javax.annotation.Nonnull;
-
-@SuppressWarnings("unused")
-class BlurViewManagerImpl {
-
- public static final String REACT_CLASS = "AndroidBlurView";
-
- public static final int defaultRadius = 10;
- public static final int defaultSampling = 10;
-
- public static @Nonnull BlurView createViewInstance(@Nonnull ThemedReactContext ctx) {
- BlurView blurView = new BlurView(ctx);
- View decorView = Objects
- .requireNonNull(ctx.getCurrentActivity())
- .getWindow()
- .getDecorView();
- blurView
- .setupWith(decorView.findViewById(android.R.id.content))
- .setFrameClearDrawable(decorView.getBackground())
- .setBlurRadius(defaultRadius);
- return blurView;
- }
-
- public static void setRadius(BlurView view, int radius) {
- view.setBlurRadius(radius);
- view.invalidate();
- }
-
- public static void setColor(BlurView view, int color) {
- view.setOverlayColor(color);
- view.invalidate();
- }
-
- public static void setDownsampleFactor(BlurView view, int factor) {}
-
- public static void setAutoUpdate(BlurView view, boolean autoUpdate) {
- view.setBlurAutoUpdate(autoUpdate);
- view.invalidate();
- }
-
- public static void setBlurEnabled(BlurView view, boolean enabled) {
- view.setBlurEnabled(enabled);
- }
-}
diff --git a/android/src/main/java/com/reactnativecommunity/blurview/ReactBlurView.java b/android/src/main/java/com/reactnativecommunity/blurview/ReactBlurView.java
new file mode 100644
index 00000000..4ca842b7
--- /dev/null
+++ b/android/src/main/java/com/reactnativecommunity/blurview/ReactBlurView.java
@@ -0,0 +1,150 @@
+package com.reactnativecommunity.blurview;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.os.Build;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import com.facebook.react.views.view.ReactViewGroup;
+
+import eightbitlab.com.blurview.BlurAlgorithm;
+import eightbitlab.com.blurview.BlurController;
+import eightbitlab.com.blurview.BlurViewFacade;
+import eightbitlab.com.blurview.NoOpController;
+import eightbitlab.com.blurview.PreDrawBlurController;
+import eightbitlab.com.blurview.RenderEffectBlur;
+import eightbitlab.com.blurview.RenderScriptBlur;
+
+/**
+ * ReactViewGroup that blurs its underlying content.
+ * Can have children and draw them over blurred background.
+ */
+public class ReactBlurView extends ReactViewGroup {
+
+ private static final String TAG = ReactBlurView.class.getSimpleName();
+ private String blurType;
+
+ private final Paint overlayPaint;
+
+ BlurController blurController = new NoOpController();
+
+ public ReactBlurView(Context context) {
+ super(context);
+ setOutlineProvider(ViewOutlineProvider.BACKGROUND);
+ setClipToOutline(true);
+ overlayPaint = new Paint();
+ setBlurType("dark");
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ boolean shouldDraw = blurController.draw(canvas);
+ if (shouldDraw) {
+ if (overlayPaint.getColor() != Color.TRANSPARENT) {
+ canvas.drawPaint(overlayPaint);
+ }
+ super.draw(canvas);
+ }
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ blurController.updateBlurViewSize();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ blurController.setBlurAutoUpdate(false);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (!isHardwareAccelerated()) {
+ Log.e(TAG, "BlurView can't be used in not hardware-accelerated window!");
+ } else {
+ blurController.setBlurAutoUpdate(true);
+ }
+ }
+
+ public BlurViewFacade setupWith(@NonNull ViewGroup rootView, BlurAlgorithm algorithm) {
+ this.blurController.destroy();
+ BlurController blurController = new PreDrawBlurController(this, rootView, getOverlayColor(), algorithm);
+ this.blurController = blurController;
+ return blurController;
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
+ public BlurViewFacade setupWith(@NonNull ViewGroup rootView) {
+ return setupWith(rootView, getBlurAlgorithm());
+ }
+
+ public BlurViewFacade setBlurRadius(float radius) {
+ return blurController.setBlurRadius(radius);
+ }
+
+ public BlurViewFacade setBlurType(String type) {
+ blurType = type;
+ overlayPaint.setXfermode(getXfermode());
+ overlayPaint.setColor(getOverlayColor());
+ return blurController;
+ }
+
+ public BlurViewFacade setBlurAutoUpdate(boolean enabled) {
+ return blurController.setBlurAutoUpdate(enabled);
+ }
+
+ public BlurViewFacade setBlurEnabled(boolean enabled) {
+ return blurController.setBlurEnabled(enabled);
+ }
+
+ @Override
+ public void setBackgroundColor(int color) {
+ blurController.setOverlayColor(color);
+ }
+
+ @NonNull
+ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
+ private BlurAlgorithm getBlurAlgorithm() {
+ BlurAlgorithm algorithm;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ algorithm = new RenderEffectBlur();
+ } else {
+ algorithm = new RenderScriptBlur(getContext());
+ }
+ return algorithm;
+ }
+
+ private int getOverlayColor() {
+ switch (blurType) {
+ case "xlight":
+ return 0xFFBEBEBE;
+ case "light":
+ return 0xFFD2D2D2;
+ default:
+ return 0xFFAAAAAA;
+ }
+ }
+
+ private PorterDuffXfermode getXfermode() {
+ switch (blurType) {
+ case "xlight":
+ return new PorterDuffXfermode(PorterDuff.Mode.SCREEN);
+ case "light":
+ return new PorterDuffXfermode(PorterDuff.Mode.OVERLAY);
+ default:
+ return new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY);
+ }
+ }
+}
diff --git a/android/src/main/res/values/attr.xml b/android/src/main/res/values/attr.xml
index 97fc4280..38dab22e 100644
--- a/android/src/main/res/values/attr.xml
+++ b/android/src/main/res/values/attr.xml
@@ -3,6 +3,5 @@
-
diff --git a/android/src/main/res/values/defaults.xml b/android/src/main/res/values/defaults.xml
index e9e00a2b..a1d69462 100644
--- a/android/src/main/res/values/defaults.xml
+++ b/android/src/main/res/values/defaults.xml
@@ -2,5 +2,4 @@
15
8
- #AAFFFFFF
diff --git a/android/src/oldarch/java/com/reactnativecommunity/blurview/BlurViewManager.java b/android/src/oldarch/java/com/reactnativecommunity/blurview/BlurViewManager.java
index 1a282095..f1ee6fab 100644
--- a/android/src/oldarch/java/com/reactnativecommunity/blurview/BlurViewManager.java
+++ b/android/src/oldarch/java/com/reactnativecommunity/blurview/BlurViewManager.java
@@ -1,53 +1,53 @@
-package com.reactnativecommunity.blurview;
-
-import androidx.annotation.NonNull;
-
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.uimanager.ThemedReactContext;
-import com.facebook.react.uimanager.ViewGroupManager;
-import com.facebook.react.uimanager.annotations.ReactProp;
-
-import eightbitlab.com.blurview.BlurView;
-
-class BlurViewManager extends ViewGroupManager {
-
- ReactApplicationContext mCallerContext;
-
- public BlurViewManager(ReactApplicationContext reactContext) {
- mCallerContext = reactContext;
- }
-
- @Override
- public BlurView createViewInstance(ThemedReactContext context) {
- return BlurViewManagerImpl.createViewInstance(context);
- }
-
- @NonNull
- @Override
- public String getName() {
- return BlurViewManagerImpl.REACT_CLASS;
- }
-
- @ReactProp(name = "blurRadius", defaultInt = BlurViewManagerImpl.defaultRadius)
- public void setRadius(BlurView view, int radius) {
- BlurViewManagerImpl.setRadius(view, radius);
- }
-
- @ReactProp(name = "overlayColor", customType = "Color")
- public void setColor(BlurView view, int color) {
- BlurViewManagerImpl.setColor(view, color);
- }
-
- @ReactProp(name = "downsampleFactor", defaultInt = BlurViewManagerImpl.defaultSampling)
- public void setDownsampleFactor(BlurView view, int factor) {}
-
- @ReactProp(name = "autoUpdate", defaultBoolean = true)
- public void setAutoUpdate(BlurView view, boolean autoUpdate) {
- BlurViewManagerImpl.setAutoUpdate(view, autoUpdate);
- }
-
- @ReactProp(name = "enabled", defaultBoolean = true)
- public void setBlurEnabled(BlurView view, boolean enabled) {
- BlurViewManagerImpl.setBlurEnabled(view, enabled);
- }
-}
+package com.reactnativecommunity.blurview;
+
+import androidx.annotation.NonNull;
+
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.uimanager.ThemedReactContext;
+import com.facebook.react.uimanager.ViewGroupManager;
+import com.facebook.react.uimanager.annotations.ReactProp;
+
+import eightbitlab.com.blurview.BlurView;
+
+class BlurViewManager extends ViewGroupManager {
+
+ ReactApplicationContext mCallerContext;
+
+ public BlurViewManager(ReactApplicationContext reactContext) {
+ mCallerContext = reactContext;
+ }
+
+ @Override
+ public BlurView createViewInstance(ThemedReactContext context) {
+ return BlurViewManagerImpl.createViewInstance(context);
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return BlurViewManagerImpl.REACT_CLASS;
+ }
+
+ @ReactProp(name = "blurRadius", defaultInt = BlurViewManagerImpl.defaultRadius)
+ public void setRadius(BlurView view, int radius) {
+ BlurViewManagerImpl.setRadius(view, radius);
+ }
+
+ @ReactProp(name = "overlayColor", customType = "Color")
+ public void setColor(BlurView view, int color) {
+ BlurViewManagerImpl.setColor(view, color);
+ }
+
+ @ReactProp(name = "downsampleFactor", defaultInt = BlurViewManagerImpl.defaultSampling)
+ public void setDownsampleFactor(BlurView view, int factor) {}
+
+ @ReactProp(name = "autoUpdate", defaultBoolean = true)
+ public void setAutoUpdate(BlurView view, boolean autoUpdate) {
+ BlurViewManagerImpl.setAutoUpdate(view, autoUpdate);
+ }
+
+ @ReactProp(name = "enabled", defaultBoolean = true)
+ public void setBlurEnabled(BlurView view, boolean enabled) {
+ BlurViewManagerImpl.setBlurEnabled(view, enabled);
+ }
+}
diff --git a/src/components/BlurView.android.tsx b/src/components/BlurView.android.tsx
index aa572fb1..a0d4de64 100644
--- a/src/components/BlurView.android.tsx
+++ b/src/components/BlurView.android.tsx
@@ -8,18 +8,9 @@ import {
} from 'react-native';
import NativeBlurView from '../fabric/BlurViewNativeComponentAndroid';
-const OVERLAY_COLORS = {
- light: 'rgba(255, 255, 255, 0.2)',
- xlight: 'rgba(255, 255, 255, 0.75)',
- dark: 'rgba(16, 12, 12, 0.64)',
-};
-
export type BlurViewProps = ViewProps & {
blurAmount?: number;
blurType?: 'dark' | 'light' | 'xlight';
- blurRadius?: number;
- downsampleFactor?: number;
- overlayColor?: string;
enabled?: boolean;
autoUpdate?: boolean;
};
@@ -27,14 +18,10 @@ export type BlurViewProps = ViewProps & {
const BlurView = forwardRef(
(
{
- downsampleFactor,
- blurRadius,
- blurAmount = 10,
blurType = 'dark',
- overlayColor,
+ blurAmount = 10,
enabled,
autoUpdate,
- children,
style,
...rest
},
@@ -50,58 +37,16 @@ const BlurView = forwardRef(
};
}, []);
- const getOverlayColor = () => {
- if (overlayColor != null) {
- return overlayColor;
- }
-
- return OVERLAY_COLORS[blurType] || OVERLAY_COLORS.dark;
- };
-
- const getBlurRadius = () => {
- if (blurRadius != null) {
- if (blurRadius > 25) {
- throw new Error(
- `[ReactNativeBlur]: blurRadius cannot be greater than 25! (was: ${blurRadius})`
- );
- }
- return blurRadius;
- }
-
- // iOS seems to use a slightly different blurring algorithm (or scale?).
- // Android blurRadius + downsampleFactor is approximately 80% of blurAmount.
- const equivalentBlurRadius = Math.round(blurAmount * 0.8);
-
- if (equivalentBlurRadius > 25) {
- return 25;
- }
- return equivalentBlurRadius;
- };
-
- const getDownsampleFactor = () => {
- if (downsampleFactor != null) {
- return downsampleFactor;
- }
-
- return blurRadius;
- };
-
return (
-
- {children}
-
+
);
}
);
diff --git a/src/components/BlurView.ios.tsx b/src/components/BlurView.ios.tsx
index 62d05ec4..b24d944a 100644
--- a/src/components/BlurView.ios.tsx
+++ b/src/components/BlurView.ios.tsx
@@ -1,4 +1,4 @@
-import React, { forwardRef } from 'react';
+import React, { forwardRef, useEffect, useState } from "react";
import { StyleSheet, ViewProps, ViewStyle, View } from 'react-native';
import NativeBlurView from '../fabric/BlurViewNativeComponent';
@@ -32,19 +32,52 @@ export type BlurViewProps = ViewProps & {
};
const BlurView = forwardRef(
- ({ blurType = 'dark', blurAmount = 10, style, ...rest }, ref) => (
-
- )
+ ({ blurType = 'dark', blurAmount = 10, style, children, ...rest }, ref) => {
+
+ const [borderStyle, setBorderStyle] = useState({});
+
+ useEffect(() => {
+ const baseStyles = StyleSheet.flatten(style) as ViewStyle;
+ const borderWidth = baseStyles.borderWidth || 0;
+ const brdrStyle = {
+ position: 'absolute',
+ top: -borderWidth,
+ left: -borderWidth,
+ right: -borderWidth,
+ bottom: -borderWidth
+ } as ViewStyle;
+
+ if (baseStyles) {
+ Object.keys(baseStyles).forEach((key) => {
+ if (key.startsWith('border')) {
+ // @ts-ignore
+ brdrStyle[key] = baseStyles[key];
+ return;
+ }
+ });
+ }
+ setBorderStyle(brdrStyle);
+ }, [style]);
+
+ return (
+
+
+
+
+ {children}
+
+ );
+ }
);
const styles = StyleSheet.create<{ transparent: ViewStyle }>({
- transparent: { backgroundColor: 'transparent' },
+ transparent: { backgroundColor: 'transparent', overflow: 'hidden' },
});
export default BlurView;
diff --git a/src/fabric/BlurViewNativeComponentAndroid.ts b/src/fabric/BlurViewNativeComponentAndroid.ts
index 59fd78f6..beef5e47 100644
--- a/src/fabric/BlurViewNativeComponentAndroid.ts
+++ b/src/fabric/BlurViewNativeComponentAndroid.ts
@@ -15,6 +15,6 @@ interface NativeProps extends ViewProps {
autoUpdate?: boolean;
}
-export default codegenNativeComponent('AndroidBlurView', {
+export default codegenNativeComponent('BlurView', {
excludedPlatforms: ['iOS'],
}) as HostComponent;