@@ -13,20 +13,16 @@ import java.text.NumberFormat
13
13
import kotlin.math.max
14
14
15
15
class BackdropVisualEffectHelper (private val view : View ) {
16
- private val bitmapCanvas = Canvas ()
16
+ private var bitmapCanvas: Canvas ? = null
17
17
private var cacheBitmap: Bitmap ? = null
18
18
private var activityDecorView: View ? = null
19
19
private var isDifferentRoot = false
20
20
21
+ private val renderingListener = RenderingListener ()
22
+ private val locations = IntArray (2 )
21
23
private val srcRect = Rect ()
22
24
private val dstRect = Rect ()
23
25
24
- private val locations = IntArray (2 )
25
- private val onPreDrawListener = ViewTreeObserver .OnPreDrawListener {
26
- renderOnce()
27
- true
28
- }
29
-
30
26
private val paint = Paint ().apply {
31
27
isAntiAlias = true
32
28
typeface = Typeface .MONOSPACE
@@ -108,6 +104,7 @@ class BackdropVisualEffectHelper(private val view: View) {
108
104
cacheBitmap?.let {
109
105
onDrawEffectedBitmap(canvas, it)
110
106
}
107
+ canvas.drawColor(overlayColor)
111
108
if (isShowDebugInfo) {
112
109
onDrawDebugInfo(canvas)
113
110
}
@@ -140,10 +137,8 @@ class BackdropVisualEffectHelper(private val view: View) {
140
137
view.context.getActivity()?.let {
141
138
activityDecorView = it.window?.decorView
142
139
}
140
+ registerRenderingListener()
143
141
activityDecorView?.let {
144
- if (it.viewTreeObserver.isAlive) {
145
- it.viewTreeObserver.addOnPreDrawListener(onPreDrawListener)
146
- }
147
142
isDifferentRoot = it.rootView != = view.rootView
148
143
if (isDifferentRoot) {
149
144
it.postInvalidate()
@@ -154,25 +149,51 @@ class BackdropVisualEffectHelper(private val view: View) {
154
149
}
155
150
156
151
private fun onDetachedFromWindow () {
152
+ unregisterRenderingListener()
153
+ visualEffect?.recycle()
154
+ }
155
+
156
+ private fun registerRenderingListener () {
157
+ activityDecorView?.let {
158
+ if (it.viewTreeObserver.isAlive) {
159
+ it.viewTreeObserver.addOnPreDrawListener(renderingListener)
160
+ }
161
+ isDifferentRoot = it.rootView != = view.rootView
162
+ if (isDifferentRoot) {
163
+ it.postInvalidate()
164
+ }
165
+ }
166
+ }
167
+
168
+ private fun unregisterRenderingListener () {
157
169
activityDecorView?.let {
158
170
if (it.viewTreeObserver.isAlive) {
159
- it.viewTreeObserver.removeOnPreDrawListener(onPreDrawListener )
171
+ it.viewTreeObserver.removeOnPreDrawListener(renderingListener )
160
172
}
161
173
}
162
- visualEffect?.recycle()
163
174
}
164
175
165
176
private fun prepare () {
166
177
val simpledWidth = (view.width / simpleSize).toInt()
167
178
val simpledHeight = (view.height / simpleSize).toInt()
168
- if (cacheBitmap == null || cacheBitmap!! .width != simpledWidth || cacheBitmap!! .height != simpledHeight) {
179
+ if (simpledWidth <= 0 || simpledHeight <= 0 ) {
180
+ bitmapCanvas = null
181
+ cacheBitmap = null
182
+ } else if (cacheBitmap == null || cacheBitmap!! .width != simpledWidth || cacheBitmap!! .height != simpledHeight) {
169
183
cacheBitmap = try {
170
184
Bitmap .createBitmap(simpledWidth, simpledHeight, Bitmap .Config .ARGB_8888 )
171
185
} catch (e: OutOfMemoryError ) {
172
186
Runtime .getRuntime().gc()
173
187
null
174
188
}
175
- bitmapCanvas.setBitmap(cacheBitmap)
189
+ if (cacheBitmap != null ) {
190
+ if (bitmapCanvas == null ) {
191
+ bitmapCanvas = Canvas ()
192
+ }
193
+ bitmapCanvas!! .setBitmap(cacheBitmap)
194
+ } else {
195
+ bitmapCanvas = null
196
+ }
176
197
}
177
198
}
178
199
@@ -182,8 +203,8 @@ class BackdropVisualEffectHelper(private val view: View) {
182
203
val decor = activityDecorView ? : return
183
204
if (! decor.isDirty) return
184
205
prepare()
206
+ val canvas = bitmapCanvas ? : return
185
207
val bitmap = cacheBitmap ? : return
186
- val canvas = bitmapCanvas
187
208
renderStartTime = System .nanoTime()
188
209
bitmap.eraseColor(Color .TRANSPARENT )
189
210
captureToBitmap(decor, canvas, bitmap)
@@ -224,7 +245,6 @@ class BackdropVisualEffectHelper(private val view: View) {
224
245
dstRect.right = view.width
225
246
dstRect.bottom = view.height
226
247
canvas.drawBitmap(bitmap, srcRect, dstRect, paint)
227
- canvas.drawColor(overlayColor)
228
248
}
229
249
230
250
private fun onDrawDebugInfo (canvas : Canvas ) {
@@ -273,5 +293,12 @@ class BackdropVisualEffectHelper(private val view: View) {
273
293
}
274
294
}
275
295
296
+ private inner class RenderingListener : ViewTreeObserver .OnPreDrawListener {
297
+ override fun onPreDraw (): Boolean {
298
+ renderOnce()
299
+ return true
300
+ }
301
+ }
302
+
276
303
private object StopException : RuntimeException()
277
304
}
0 commit comments