@@ -1076,6 +1076,29 @@ class QuillRawEditorState extends EditorState
10761076 .stopCurrentVerticalRunIfSelectionChanges ();
10771077 }
10781078
1079+ late double _lastBottomViewInset;
1080+
1081+ @override
1082+ void didChangeMetrics () {
1083+ if (! mounted) {
1084+ return ;
1085+ }
1086+
1087+ // https://github.com/flutter/flutter/blob/3.29.0/packages/flutter/lib/src/widgets/editable_text.dart#L4311
1088+ final view = View .of (context);
1089+ if (_lastBottomViewInset != view.viewInsets.bottom) {
1090+ SchedulerBinding .instance.addPostFrameCallback ((_) {
1091+ _selectionOverlay? .updateForScroll ();
1092+ }, debugLabel: 'EditableText.updateForScroll' );
1093+ if (_lastBottomViewInset < view.viewInsets.bottom) {
1094+ // Because the metrics change signal from engine will come here every frame
1095+ // (on both iOS and Android). So we don't need to show caret with animation.
1096+ _scheduleShowCaretOnScreen (withAnimation: false );
1097+ }
1098+ }
1099+ _lastBottomViewInset = view.viewInsets.bottom;
1100+ }
1101+
10791102 void _onChangeTextEditingValue ([bool ignoreCaret = false ]) {
10801103 updateRemoteValueIfNeeded ();
10811104 if (ignoreCaret) {
@@ -1151,6 +1174,7 @@ class QuillRawEditorState extends EditorState
11511174 _updateOrDisposeSelectionOverlayIfNeeded ();
11521175 if (_hasFocus) {
11531176 WidgetsBinding .instance.addObserver (this );
1177+ _lastBottomViewInset = View .of (context).viewInsets.bottom;
11541178 _scheduleShowCaretOnScreen (withAnimation: true );
11551179 } else {
11561180 WidgetsBinding .instance.removeObserver (this );
0 commit comments