diff --git a/packages/fleather/lib/src/widgets/editor.dart b/packages/fleather/lib/src/widgets/editor.dart index 666bd210..d1e6ee57 100644 --- a/packages/fleather/lib/src/widgets/editor.dart +++ b/packages/fleather/lib/src/widgets/editor.dart @@ -1474,6 +1474,7 @@ class RawEditorState extends EditorState if (_hasFocus) { // Listen for changing viewInsets, which indicates keyboard showing up. WidgetsBinding.instance.addObserver(this); + _lastBottomViewInset = View.of(context).viewInsets.bottom; _showCaretOnScreen(); // _lastBottomViewInset = WidgetsBinding.instance.window.viewInsets.bottom; // if (!_value.selection.isValid) { @@ -1514,7 +1515,7 @@ class RawEditorState extends EditorState bool _showCaretOnScreenScheduled = false; - void _showCaretOnScreen() { + void _showCaretOnScreen([bool withAnimation = true]) { if (!widget.showCursor || _showCaretOnScreenScheduled) { return; } @@ -1539,11 +1540,16 @@ class RawEditorState extends EditorState ); if (offset != null) { - _scrollController.animateTo( - math.min(offset, _scrollController.position.maxScrollExtent), - duration: _caretAnimationDuration, - curve: _caretAnimationCurve, - ); + if (withAnimation) { + _scrollController.animateTo( + math.min(offset, _scrollController.position.maxScrollExtent), + duration: _caretAnimationDuration, + curve: _caretAnimationCurve, + ); + } else { + _scrollController.jumpTo( + math.min(offset, _scrollController.position.maxScrollExtent)); + } } }); } @@ -1569,6 +1575,28 @@ class RawEditorState extends EditorState } } + late double _lastBottomViewInset; + + @override + void didChangeMetrics() { + super.didChangeMetrics(); + if (!mounted) { + return; + } + final bottomViewInset = View.of(context).viewInsets.bottom; + if (_lastBottomViewInset != bottomViewInset) { + SchedulerBinding.instance.addPostFrameCallback((_) { + _selectionOverlay?.updateForScroll(); + }); + if (_lastBottomViewInset < bottomViewInset) { + // Because the metrics change signal from engine will come here every frame + // (on both iOS and Android). So we don't need to show caret with animation. + _showCaretOnScreen(false); + } + } + _lastBottomViewInset = bottomViewInset; + } + // On MacOS some actions are sent as selectors. We need to manually find the right Action and invoke it. // Ref: https://github.com/flutter/flutter/blob/3.7.0/packages/flutter/lib/src/widgets/editable_text.dart#L3731 @override