@sbaiahmed1/react-native-blur 4.5.5-beta.3 → 4.5.5-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package com.sbaiahmed1.reactnativeblur
|
|
2
2
|
|
|
3
|
+
import android.app.Activity
|
|
3
4
|
import android.content.Context
|
|
5
|
+
import android.content.ContextWrapper
|
|
4
6
|
import android.graphics.Color
|
|
5
7
|
import android.graphics.Outline
|
|
6
8
|
import android.util.AttributeSet
|
|
@@ -10,6 +12,7 @@ import android.view.View
|
|
|
10
12
|
import android.view.ViewGroup
|
|
11
13
|
import android.view.ViewOutlineProvider
|
|
12
14
|
import android.view.ViewTreeObserver
|
|
15
|
+
import com.facebook.react.bridge.ReactContext
|
|
13
16
|
import com.qmdeve.blurview.widget.BlurViewGroup
|
|
14
17
|
import com.qmdeve.blurview.base.BaseBlurViewGroup
|
|
15
18
|
import androidx.core.graphics.toColorInt
|
|
@@ -188,10 +191,13 @@ class ReactNativeBlurView : BlurViewGroup {
|
|
|
188
191
|
|
|
189
192
|
/**
|
|
190
193
|
* Finds the optimal view to use as blur capture root.
|
|
191
|
-
* Priority: nearest react-native-screens Screen > android.R.id.content > parent
|
|
194
|
+
* Priority: nearest react-native-screens Screen > android.R.id.content in parent chain > activity content > parent
|
|
195
|
+
*
|
|
196
|
+
* This handles both regular screens and modals — modals have their own window/view tree,
|
|
197
|
+
* so we walk up the parent chain for android.R.id.content before falling back to the activity.
|
|
192
198
|
*/
|
|
193
199
|
private fun findOptimalBlurRoot(): ViewGroup? {
|
|
194
|
-
return findNearestScreenAncestor() ?:
|
|
200
|
+
return findNearestScreenAncestor() ?: getAppRootFallback()
|
|
195
201
|
}
|
|
196
202
|
|
|
197
203
|
/**
|
|
@@ -210,18 +216,45 @@ class ReactNativeBlurView : BlurViewGroup {
|
|
|
210
216
|
}
|
|
211
217
|
|
|
212
218
|
/**
|
|
213
|
-
*
|
|
219
|
+
* Walks up the view parent chain looking for android.R.id.content (works in modals
|
|
220
|
+
* which have their own content root), then falls back to the activity's content view.
|
|
214
221
|
*/
|
|
215
|
-
private fun
|
|
222
|
+
private fun getAppRootFallback(): ViewGroup? {
|
|
223
|
+
// Walk up the parent chain — catches modals which have their own android.R.id.content
|
|
224
|
+
var parent = this.parent
|
|
225
|
+
while (parent != null) {
|
|
226
|
+
if (parent is ViewGroup && parent.id == android.R.id.content) {
|
|
227
|
+
return parent
|
|
228
|
+
}
|
|
229
|
+
parent = parent.parent
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Fall back to the activity's content view
|
|
216
233
|
try {
|
|
217
|
-
val activity =
|
|
234
|
+
val activity = getActivityFromContext()
|
|
218
235
|
activity?.findViewById<ViewGroup>(android.R.id.content)?.let { return it }
|
|
219
236
|
} catch (e: Exception) {
|
|
220
|
-
logDebug("Could not access activity
|
|
237
|
+
logDebug("Could not access activity root view: ${e.message}")
|
|
221
238
|
}
|
|
239
|
+
|
|
222
240
|
return this.parent as? ViewGroup
|
|
223
241
|
}
|
|
224
242
|
|
|
243
|
+
/**
|
|
244
|
+
* Resolves an Activity from the view's context.
|
|
245
|
+
* Priority: ReactContext.currentActivity > ContextWrapper unwrap chain.
|
|
246
|
+
*/
|
|
247
|
+
private fun getActivityFromContext(): Activity? {
|
|
248
|
+
(context as? ReactContext)?.currentActivity?.let { return it }
|
|
249
|
+
|
|
250
|
+
var ctx: Context? = context
|
|
251
|
+
while (ctx != null) {
|
|
252
|
+
if (ctx is Activity) return ctx
|
|
253
|
+
ctx = (ctx as? ContextWrapper)?.baseContext
|
|
254
|
+
}
|
|
255
|
+
return null
|
|
256
|
+
}
|
|
257
|
+
|
|
225
258
|
/**
|
|
226
259
|
* Initialize the blur view with current settings.
|
|
227
260
|
* Called after the view is attached and the blur root has been swapped.
|
package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeProgressiveBlurView.kt
CHANGED
|
@@ -160,7 +160,9 @@ class ReactNativeProgressiveBlurView : FrameLayout {
|
|
|
160
160
|
* Redirects the internal BlurView's blur capture root from the activity decor view
|
|
161
161
|
* to the nearest react-native-screens Screen ancestor.
|
|
162
162
|
*
|
|
163
|
-
* BaseBlurView
|
|
163
|
+
* BaseBlurView (QmBlurView 1.1.4) field visibility:
|
|
164
|
+
* public — mDecorView, mDifferentRoot, preDrawListener (direct access)
|
|
165
|
+
* private — mForceRedraw (requires reflection)
|
|
164
166
|
*/
|
|
165
167
|
private fun swapBlurRootToScreenAncestor() {
|
|
166
168
|
val bv = blurView ?: return
|
|
@@ -178,15 +180,24 @@ class ReactNativeProgressiveBlurView : FrameLayout {
|
|
|
178
180
|
logDebug("Could not remove old pre-draw listener: ${e.message}")
|
|
179
181
|
}
|
|
180
182
|
|
|
181
|
-
// Set new root
|
|
183
|
+
// Set new root (public field)
|
|
182
184
|
bv.mDecorView = newRoot
|
|
183
185
|
|
|
184
186
|
// Add listener to new root
|
|
185
187
|
newRoot.viewTreeObserver.addOnPreDrawListener(listener)
|
|
186
188
|
|
|
187
|
-
// Update mDifferentRoot flag
|
|
189
|
+
// Update mDifferentRoot flag (public field)
|
|
188
190
|
bv.mDifferentRoot = newRoot.rootView != bv.rootView
|
|
189
191
|
|
|
192
|
+
// Force a redraw (private field — requires reflection)
|
|
193
|
+
try {
|
|
194
|
+
val forceRedrawField = bv.javaClass.superclass.getDeclaredField("mForceRedraw")
|
|
195
|
+
forceRedrawField.isAccessible = true
|
|
196
|
+
forceRedrawField.setBoolean(bv, true)
|
|
197
|
+
} catch (e: NoSuchFieldException) {
|
|
198
|
+
logWarning("Could not set mForceRedraw via reflection: ${e.message}")
|
|
199
|
+
}
|
|
200
|
+
|
|
190
201
|
logDebug("Progressive blur: swapped root to ${newRoot.javaClass.simpleName}")
|
|
191
202
|
}
|
|
192
203
|
} catch (e: Exception) {
|
|
@@ -196,10 +207,13 @@ class ReactNativeProgressiveBlurView : FrameLayout {
|
|
|
196
207
|
|
|
197
208
|
/**
|
|
198
209
|
* Finds the optimal view to use as blur capture root.
|
|
199
|
-
* Priority: nearest react-native-screens Screen > android.R.id.content > parent
|
|
210
|
+
* Priority: nearest react-native-screens Screen > android.R.id.content in parent chain > activity content > parent
|
|
211
|
+
*
|
|
212
|
+
* This handles both regular screens and modals — modals have their own window/view tree,
|
|
213
|
+
* so we walk up the parent chain for android.R.id.content before falling back to the activity.
|
|
200
214
|
*/
|
|
201
215
|
private fun findOptimalBlurRoot(): ViewGroup? {
|
|
202
|
-
return findNearestScreenAncestor() ?:
|
|
216
|
+
return findNearestScreenAncestor() ?: getAppRootFallback()
|
|
203
217
|
}
|
|
204
218
|
|
|
205
219
|
/**
|
|
@@ -217,16 +231,27 @@ class ReactNativeProgressiveBlurView : FrameLayout {
|
|
|
217
231
|
}
|
|
218
232
|
|
|
219
233
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
234
|
+
* Walks up the view parent chain looking for android.R.id.content (works in modals
|
|
235
|
+
* which have their own content root), then falls back to the activity's content view.
|
|
222
236
|
*/
|
|
223
|
-
private fun
|
|
237
|
+
private fun getAppRootFallback(): ViewGroup? {
|
|
238
|
+
// Walk up the parent chain — catches modals which have their own android.R.id.content
|
|
239
|
+
var parent = this.parent
|
|
240
|
+
while (parent != null) {
|
|
241
|
+
if (parent is ViewGroup && parent.id == android.R.id.content) {
|
|
242
|
+
return parent
|
|
243
|
+
}
|
|
244
|
+
parent = parent.parent
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Fall back to the activity's content view
|
|
224
248
|
try {
|
|
225
249
|
val activity = getActivityFromContext()
|
|
226
250
|
activity?.findViewById<ViewGroup>(android.R.id.content)?.let { return it }
|
|
227
251
|
} catch (e: Exception) {
|
|
228
|
-
logDebug("Could not access activity
|
|
252
|
+
logDebug("Could not access activity root view: ${e.message}")
|
|
229
253
|
}
|
|
254
|
+
|
|
230
255
|
return this.parent as? ViewGroup
|
|
231
256
|
}
|
|
232
257
|
|