Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: predictive back gesture handler (correct end event) #814

Merged
merged 3 commits into from
Feb 20, 2025

Conversation

kirillzyusko
Copy link
Owner

@kirillzyusko kirillzyusko commented Feb 18, 2025

📜 Description

Fixed incorrect end event after cancelling predictive back gesture.

💡 Motivation and Context

The problem was in fact that when keyboard gets shown in onEnd callback we get keyboard height as 0, because insets were not applied yet.

I had this problem two years ago (when I implemented interactive keyboard dismissal), but back to the times I solved it via adding InteractiveProvider.isShown and it was working well, because the only one class could control keyboard position and it was my class. However starting from Android 15 keyboard position can be controlled by OS itself, so the trick with InteractiveProvider.isShown is not working anymore.

After discovering various approaches how to handle it I found only two ways:

1️⃣ Pre-save insets in onApplyWindowInsets

While it seems preferable option, I still don't understand how it can be utilized in that fix, because onApplyWindowInsets will be dispatched in the beginning of the animation and in onEnd we will not be able to determine whether keyboard has been actually closed or returned back.

Warning

The approach with saving last keyboard height in onProgress handler and based on that dispatch an event in onEnd may be not good, because keyboard animation can be interrupted and potentially it can cause more bugs, see #704 for more details

2️⃣ Check insets after layout pass

This seems to be one and the most reliable solution (though it adds a delay to onEnd event, but in my understanding it's not very critical). With this approach we can be sure, that all new insets are applied and we can reak keyboard frame properly.


Upcoming questions that popped up in my head:

  • should we remove InteractiveKeyboardProvider completely/should we consider predictive back gesture dismissal as interactive keyboard dismissal - is a good question, but if we do this, we'll treat back predictive gesture as interactive keyboard dismissal (in fact it is interactive dismissal), and in this case we'll send onInteractive instead of onMove. It can be a breaking change and people (including me) may associate onInteractive event only to be present with KeyboardGestureArea, so for now let's keep it for a sake of backward compatibility.
  • is async the only one way to manage this? Can't we pre-memoize start/onApplyInsets and re-use it there? - at the moment I don't understand how memoization of insets in onApplyInsets/onStart can help us to detect final keyboard position in onEnd. Maybe it's doable, but for now let's stick with async approach. If we discover a new way how to handle everything synchronously we always can re-work that piece of the code and improve it 😎

Closes #810

📢 Changelog

Android

  • added isKeyboardInteractive getter;
  • wrap onEnd body in Runnable;
  • based on isKeyboardInteractive either execute runnable immediately or after a layout pass;
  • removed InteractiveProvider.isShown;

🤔 How Has This Been Tested?

Tested manually on Pixel 7 Pro (Android 15).

📸 Screenshots (if appropriate):

telegram-cloud-document-2-5312269435799625339.mp4

📝 Checklist

  • CI successfully passed
  • I added new mocks and corresponding unit-tests if library API was changed

@kirillzyusko kirillzyusko added 🐛 bug Something isn't working 🤖 android Android specific 👆 interactive keyboard Anything related to interactive keyboard dismissing labels Feb 18, 2025
@kirillzyusko kirillzyusko self-assigned this Feb 18, 2025
Copy link
Contributor

github-actions bot commented Feb 18, 2025

📊 Package size report

Current size Target Size Difference
167669 bytes 167643 bytes 26 bytes 📈

@kirillzyusko kirillzyusko force-pushed the fix/predictive-back-gesture-handler-correct-state branch from 0ac3675 to 19250a1 Compare February 19, 2025 19:40
@kirillzyusko kirillzyusko marked this pull request as ready for review February 20, 2025 09:56
@kirillzyusko kirillzyusko merged commit 4793906 into main Feb 20, 2025
16 checks passed
@kirillzyusko kirillzyusko deleted the fix/predictive-back-gesture-handler-correct-state branch February 20, 2025 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Android specific 🐛 bug Something isn't working 👆 interactive keyboard Anything related to interactive keyboard dismissing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect end event after cancelling predictive back gesture
1 participant