@@ -1076,6 +1076,29 @@ class QuillRawEditorState extends EditorState
1076
1076
.stopCurrentVerticalRunIfSelectionChanges ();
1077
1077
}
1078
1078
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
+
1079
1102
void _onChangeTextEditingValue ([bool ignoreCaret = false ]) {
1080
1103
updateRemoteValueIfNeeded ();
1081
1104
if (ignoreCaret) {
@@ -1151,6 +1174,7 @@ class QuillRawEditorState extends EditorState
1151
1174
_updateOrDisposeSelectionOverlayIfNeeded ();
1152
1175
if (_hasFocus) {
1153
1176
WidgetsBinding .instance.addObserver (this );
1177
+ _lastBottomViewInset = View .of (context).viewInsets.bottom;
1154
1178
_scheduleShowCaretOnScreen (withAnimation: true );
1155
1179
} else {
1156
1180
WidgetsBinding .instance.removeObserver (this );
0 commit comments