@@ -5812,12 +5812,111 @@ void main() {
58125812 state.bringIntoView (TextPosition (offset: controller.text.length));
58135813
58145814 await tester.pumpAndSettle ();
5815- // The SingleChildScrollView is scrolled instead of the EditableText to
5816- // reveal the caret.
5815+ // The SingleChildScrollView is scrolled instead of the EditableText to reveal the caret.
58175816 expect (outerController.offset, outerController.position.maxScrollExtent);
58185817 expect (editableScrollController.offset, 0 );
58195818 });
58205819
5820+ testWidgets ('bringIntoView centers the viewport on caret when the caret is wider than the viewport' , (WidgetTester tester) async {
5821+ const String text = 'to coz ze ze Szwecji' ;
5822+ final TextEditingController controller = TextEditingController (text: text);
5823+
5824+ await tester.pumpWidget (MaterialApp (
5825+ home: Align (
5826+ alignment: Alignment .topLeft,
5827+ child: SizedBox (
5828+ width: 32.0 ,
5829+ height: 100.0 ,
5830+ child: EditableText (
5831+ showSelectionHandles: true ,
5832+ controller: controller,
5833+ focusNode: FocusNode (),
5834+ style: const TextStyle (fontFamily: 'Ahem' , fontSize: 48.0 , height: 1.0 ),
5835+ cursorColor: Colors .blue,
5836+ cursorWidth: 48.0 ,
5837+ backgroundCursorColor: Colors .grey,
5838+ selectionControls: materialTextSelectionControls,
5839+ keyboardType: TextInputType .text,
5840+ ),
5841+ ),
5842+ ),
5843+ ));
5844+
5845+ final EditableTextState state = tester.state <EditableTextState >(find.byType (EditableText ));
5846+ final RenderEditable renderEditable = state.renderEditable;
5847+ final Scrollable scrollable = tester.widget <Scrollable >(find.byType (Scrollable ));
5848+
5849+ expect (scrollable.controller! .position.viewportDimension, equals (32.0 ));
5850+ expect (scrollable.controller! .offset, 0.0 );
5851+ expect (renderEditable.maxScrollExtent, equals (977.0 ));
5852+
5853+ state.bringIntoView (const TextPosition (offset: 2 ));
5854+ await tester.pumpAndSettle ();
5855+ expect (scrollable.controller! .offset, 2 * 48.0 + 48.0 / 2 - 32.0 / 2 );
5856+
5857+ state.bringIntoView (const TextPosition (offset: 5 ));
5858+ await tester.pumpAndSettle ();
5859+ expect (scrollable.controller! .offset, 5 * 48.0 + 48.0 / 2 - 32.0 / 2 );
5860+
5861+ state.bringIntoView (const TextPosition (offset: 7 ));
5862+ await tester.pumpAndSettle ();
5863+ expect (scrollable.controller! .offset, 7 * 48.0 + 48.0 / 2 - 32.0 / 2 );
5864+
5865+ state.bringIntoView (const TextPosition (offset: 9 ));
5866+ await tester.pumpAndSettle ();
5867+ expect (scrollable.controller! .offset, 9 * 48.0 + 48.0 / 2 - 32.0 / 2 );
5868+ });
5869+
5870+ testWidgets ('bringIntoView centers the viewport on caret when the caret is taller than the viewport' , (WidgetTester tester) async {
5871+ const String text = 'to\n coz\n ze\n ze\n Szwecji' ;
5872+ final TextEditingController controller = TextEditingController (text: text);
5873+
5874+ await tester.pumpWidget (MaterialApp (
5875+ home: Align (
5876+ alignment: Alignment .topLeft,
5877+ child: SizedBox (
5878+ width: 500.0 ,
5879+ height: 32.0 ,
5880+ child: EditableText (
5881+ showSelectionHandles: true ,
5882+ maxLines: null ,
5883+ controller: controller,
5884+ focusNode: FocusNode (),
5885+ style: const TextStyle (fontFamily: 'Ahem' , fontSize: 48.0 , height: 1.0 ),
5886+ cursorColor: Colors .blue,
5887+ backgroundCursorColor: Colors .grey,
5888+ selectionControls: materialTextSelectionControls,
5889+ keyboardType: TextInputType .text,
5890+ ),
5891+ ),
5892+ ),
5893+ ));
5894+
5895+ final EditableTextState state = tester.state <EditableTextState >(find.byType (EditableText ));
5896+ final RenderEditable renderEditable = state.renderEditable;
5897+ final Scrollable scrollable = tester.widget <Scrollable >(find.byType (Scrollable ));
5898+
5899+ expect (scrollable.controller! .position.viewportDimension, equals (32.0 ));
5900+ expect (scrollable.controller! .offset, 0.0 );
5901+ expect (renderEditable.maxScrollExtent, equals (208.0 ));
5902+
5903+ state.bringIntoView (const TextPosition (offset: 3 ));
5904+ await tester.pumpAndSettle ();
5905+ expect (scrollable.controller! .offset, 48.0 + 48.0 / 2 - 32.0 / 2 );
5906+
5907+ state.bringIntoView (const TextPosition (offset: 7 ));
5908+ await tester.pumpAndSettle ();
5909+ expect (scrollable.controller! .offset, 2 * 48.0 + 48.0 / 2 - 32.0 / 2 );
5910+
5911+ state.bringIntoView (const TextPosition (offset: 10 ));
5912+ await tester.pumpAndSettle ();
5913+ expect (scrollable.controller! .offset, 3 * 48.0 + 48.0 / 2 - 32.0 / 2 );
5914+
5915+ state.bringIntoView (const TextPosition (offset: 13 ));
5916+ await tester.pumpAndSettle ();
5917+ expect (scrollable.controller! .offset, 4 * 48.0 + 48.0 / 2 - 32.0 / 2 );
5918+ });
5919+
58215920 testWidgets ('bringIntoView does nothing if the physics prohibits implicit scrolling' , (WidgetTester tester) async {
58225921 final TextEditingController controller = TextEditingController (text: testText * 20 );
58235922 final ScrollController scrollController = ScrollController ();
@@ -5844,7 +5943,6 @@ void main() {
58445943 ));
58455944 }
58465945
5847-
58485946 await buildWithPhysics ();
58495947 expect (scrollController.offset, 0 );
58505948
0 commit comments