@@ -199,7 +199,17 @@ class ImeSyncDeferringInsetsCallback extends WindowInsetsAnimation.Callback
199
199
200
200
private View view ;
201
201
private WindowInsets lastWindowInsets ;
202
- private boolean started = false ;
202
+ // True when an animation that matches deferredInsetTypes is active.
203
+ //
204
+ // While this is active, this class will capture the initial window inset
205
+ // sent into lastWindowInsets by flagging needsSave to true, and will hold
206
+ // onto the intitial inset until the animation is completed, when it will
207
+ // re-dispatch the inset change.
208
+ private boolean animating = false ;
209
+ // When an animation begins, android sends a WindowInset with the final
210
+ // state of the animation. When needsSave is true, we know to capture this
211
+ // initial WindowInset.
212
+ private boolean needsSave = false ;
203
213
204
214
ImeSyncDeferringInsetsCallback (
205
215
@ NonNull View view , int overlayInsetTypes , int deferredInsetTypes ) {
@@ -212,34 +222,38 @@ class ImeSyncDeferringInsetsCallback extends WindowInsetsAnimation.Callback
212
222
@ Override
213
223
public WindowInsets onApplyWindowInsets (View view , WindowInsets windowInsets ) {
214
224
this .view = view ;
215
- if (started ) {
225
+ if (needsSave ) {
226
+ // Store the view and insets for us in onEnd() below. This captured inset
227
+ // is not part of the animation and instead, represents the final state
228
+ // of the inset after the animation is completed. Thus, we defer the processing
229
+ // of this WindowInset until the animation completes.
230
+ lastWindowInsets = windowInsets ;
231
+ needsSave = false ;
232
+ }
233
+ if (animating ) {
216
234
// While animation is running, we consume the insets to prevent disrupting
217
235
// the animation, which skips this implementation and calls the view's
218
236
// onApplyWindowInsets directly to avoid being consumed here.
219
237
return WindowInsets .CONSUMED ;
220
238
}
221
239
222
- // Store the view and insets for us in onEnd() below
223
- lastWindowInsets = windowInsets ;
224
-
225
240
// If no animation is happening, pass the insets on to the view's own
226
241
// inset handling.
227
242
return view .onApplyWindowInsets (windowInsets );
228
243
}
229
244
230
245
@ Override
231
- public WindowInsetsAnimation .Bounds onStart (
232
- WindowInsetsAnimation animation , WindowInsetsAnimation .Bounds bounds ) {
246
+ public void onPrepare (WindowInsetsAnimation animation ) {
233
247
if ((animation .getTypeMask () & deferredInsetTypes ) != 0 ) {
234
- started = true ;
248
+ animating = true ;
249
+ needsSave = true ;
235
250
}
236
- return bounds ;
237
251
}
238
252
239
253
@ Override
240
254
public WindowInsets onProgress (
241
255
WindowInsets insets , List <WindowInsetsAnimation > runningAnimations ) {
242
- if (!started ) {
256
+ if (!animating || needsSave ) {
243
257
return insets ;
244
258
}
245
259
boolean matching = false ;
@@ -280,10 +294,10 @@ public WindowInsets onProgress(
280
294
281
295
@ Override
282
296
public void onEnd (WindowInsetsAnimation animation ) {
283
- if (started && (animation .getTypeMask () & deferredInsetTypes ) != 0 ) {
297
+ if (animating && (animation .getTypeMask () & deferredInsetTypes ) != 0 ) {
284
298
// If we deferred the IME insets and an IME animation has finished, we need to reset
285
299
// the flags
286
- started = false ;
300
+ animating = false ;
287
301
288
302
// And finally dispatch the deferred insets to the view now.
289
303
// Ideally we would just call view.requestApplyInsets() and let the normal dispatch
0 commit comments