flutter_keyboard_controller 1.0.1
flutter_keyboard_controller: ^1.0.1 copied to clipboard
Smooth, frame-by-frame keyboard animation tracking for Flutter. Includes KeyboardChatScrollView, KeyboardToolbar, KeyboardStickyView, KeyboardAwareScrollView, and KeyboardAvoidingView — everything you [...]
1.0.1 #
Android — Critical fix: keyboard-type switch height tracking #
-
Root cause:
WindowInsetsAnimationCompat.Callbackonly fires during animated transitions. On Samsung and other Android devices, switching keyboard type (e.g. text → number) triggers a static layout pass with no animation —onProgress/onEndare never called, leavingheightNotifierstuck at the old keyboard height. The toolbar and auto-scroll would appear mispositioned after the switch. -
Fix: Added
setOnApplyWindowInsetsListeneras a safety-net listener alongside the animation callback. It fires on every inset change regardless of animation, ensuringheightNotifieris always up to date. TheisAnimatingflag prevents duplicate events when both listeners fire for the same transition.
Android — Toolbar positioning: Positioned inside ValueListenableBuilder inside Stack #
-
Root cause: Returning a
Positionedwidget from inside aValueListenableBuilder.builderthat is itself a child ofStackcauses undefined layout on Android —Positionedmust be a direct child ofStack's render tree to receiveStackParentData. -
Fix: Changed to
Positioned.fill(child: VLB(...))withAlign + Padding(bottom: kbH)inside the builder — the same pattern used byKeyboardStickyView. No more black screen or layout artifacts on Android.
Android — Toolbar type-switch flicker: pendingHide lambda capture #
-
Root cause: The deferred
didHidesuppression used aRunnable(captured by value).cancelPendingHide()setpendingHideRunnable = nullbut the already-queuedRunnablestill ran and emittedkeyboardDidHide, causingheightNotifierto reset and the toolbar to flicker. -
Fix: Changed
pendingHideRunnable: Runnable?to a Kotlin lambda variablependingHide: (() -> Unit)?. ThedecorView.post {}closure capturespendingHideby reference — aftercancelPendingHide()sets it tonull,pendingHide?.invoke()is safely skipped.
Architecture: KeyboardGeometryService #
- Extracted Element Tree traversal (
visitAncestorElements) and scroll-offset math (RenderBox.localToGlobal) from_KeyboardAwareScrollViewStateintolib/src/services/KeyboardGeometryService. KeyboardAwareScrollViewis now a thin UI layer; geometry logic is independently unit-testable without rendering a widget tree.
KeyboardAwareScrollView — replaced Future.delayed with addPostFrameCallback #
- Removed the arbitrary
focusScrollDelay(previously 120 ms) in favour ofWidgetsBinding.instance.addPostFrameCallback. _scrollGenerationcounter still cancels stale callbacks from rapid taps._isDismissing+ModalRoute.isCurrentguard still blocks scroll when a bottom sheet opens.- Android's new
setOnApplyWindowInsetsListenersets_isDismissingpromptly so the single-frame (≈ 16 ms) window is sufficient on all devices.
API cleanup (non-breaking) #
- Removed
focusScrollDelayparameter fromKeyboardAwareScrollView— was no longer used after theaddPostFrameCallbackmigration. Parameter was never mentioned in guides; removal has no user impact. - Removed private dead code
_resolveScrollContextLegacyfrom_KeyboardAwareScrollViewState.
KeyboardToolbar new features #
actions: List<KeyboardToolbarAction>— custom icon buttons with optional selected-state circle highlight.margin/borderRadius— floating pill style above keyboard.KeyboardDismissBehaviorinKeyboardToolbarScaffoldno longer requiresresizeToAvoidBottomInset: true; usesKeyboardStickyViewviaStack + Positioned.fillwhenfalse.toolbarScrollClearance— auto-injects extra scroll padding into nestedKeyboardAwareScrollViewviaKeyboardToolbarInsetInheritedWidget.
KeyboardChatScrollView — fix whenAtEnd mode missing rebuild #
_onScrollnow callssetStatewhen_wasAtEndchanges so_liftPaddingForre-evaluates correctly while keyboard is already visible.
README #
- Added visual preview table (GIFs).
- Added
KeyboardGeometryServiceand Android two-layer tracking architecture notes. - Replaced "2 large vs 18 micro rebuilds" with O(N) vs O(1) notation.
- Added
KeyboardScrollBoundaryusage in the mainKeyboardAwareScrollViewcode example. - Added
KeyboardProviderplacement warning (must wrapMaterialApp, notScaffold). - Added
heightbehaviorRenderBoxtight-vs-loose constraint explanation.
1.0.0 #
Breaking change #
KeyboardProvidernow acceptsdismissBehaviorparameter — defaults toKeyboardDismissBehavior.manual(no change in existing behavior).
New feature #
KeyboardDismissBehaviorenum added toKeyboardProvider:manual— keyboard never auto-dismissed (default, backward-compatible)onTap— dismiss when user taps anywhere outside a focused inputonDrag— dismiss when user starts scrollingonTapAndDrag— dismiss on both tap and scroll
0.0.4 #
- Fix: Remove Package.swift on iOS
0.0.3 #
Update README #
- Rewrote intro — removed inaccurate claim about
MediaQuery.viewInsetsOf, replaced with accurate description of targeted rebuild advantage - Updated comparison table:
MediaQuery.viewInsetsOfvs library, removed misleading rows, added real differentiators (rebuild scope, progress 0→1, event types, interactive dismiss,setInputMode,preload) - Updated installation version to
^0.0.2
0.0.2 #
Update README #
- Added full parameter tables for all widgets with defaults
- Added
KeyboardProviderdedicated section - Added
FocusedInputLayout,FocusedInputTextChangedEvent,FocusedInputSelectionChangedEventdocumentation - Added
KeyboardEventType.interactiveto event reference - Added
KeyboardControllerScopemethod table - Added
AndroidSoftInputModebehavior explanation - Added
KeyboardAwareScrollViewfull params + fallback note - Added
KeyboardAvoidingView.enabledparam + layout-stability explanation - Added
KeyboardChatScrollView.onEndVisible+safeAreaBottomdocumentation - Added
KeyboardAnimationevent listening example
0.0.1 #
Initial release #
- KeyboardProvider — root widget that tracks keyboard state via native platform channels. Wraps your app once; all descendants get access to live keyboard data.
- KeyboardAnimation — exposes
heightNotifier,progressNotifier, andisVisibleNotifierasValueNotifiers for efficient, targeted rebuilds. - KeyboardController — static API to dismiss keyboard, query visibility, and set Android soft-input mode.
- KeyboardChatScrollView — chat-optimised scroll view with four lift behaviours:
always,whenAtEnd,persistent,never. - KeyboardStickyView — sticks any widget to the top of the keyboard and animates it frame-by-frame.
- KeyboardToolbar — Prev / Next / Done toolbar above the keyboard with customisable labels, arrow colour, and Done colour.
- KeyboardToolbarScaffold — convenience scaffold that wires up
KeyboardToolbarwith a single line. - KeyboardAwareScrollView — auto-scrolls to keep the focused
TextFieldvisible as the keyboard opens. - KeyboardAvoidingView — lightweight alternative to Flutter's
resizeToAvoidBottomInsetfor fine-grained control. - iOS: frame-accurate keyboard tracking via
CADisplayLinkwith easing-curve interpolation. - Android: frame-accurate tracking via
WindowInsetsAnimationCompat. - Android:
setInputMode/setDefaultModesupport.