diff --git a/packages/flutter/lib/src/material/search.dart b/packages/flutter/lib/src/material/search.dart index 8062079eff..f56eeb93c2 100644 --- a/packages/flutter/lib/src/material/search.dart +++ b/packages/flutter/lib/src/material/search.dart @@ -248,9 +248,14 @@ abstract class SearchDelegate { /// If the user taps on a suggestion provided by [buildSuggestions] this /// string should be updated to that suggestion via the setter. String get query => _queryTextController.text; + + /// Changes the current query string. + /// + /// Setting the query string programmatically moves the cursor to the end of the text field. set query(String value) { assert(query != null); _queryTextController.text = value; + _queryTextController.selection = TextSelection.fromPosition(TextPosition(offset: _queryTextController.text.length)); } /// Transition from the suggestions returned by [buildSuggestions] to the diff --git a/packages/flutter/test/material/search_test.dart b/packages/flutter/test/material/search_test.dart index 32c968fa80..9eaf2c8a50 100644 --- a/packages/flutter/test/material/search_test.dart +++ b/packages/flutter/test/material/search_test.dart @@ -40,6 +40,27 @@ void main() { TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null); }); + testWidgets('Changing query moves cursor to the end of query', (WidgetTester tester) async { + final _TestSearchDelegate delegate = _TestSearchDelegate(); + + await tester.pumpWidget(TestHomePage(delegate: delegate)); + await tester.tap(find.byTooltip('Search')); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 300)); + + delegate.query = 'Foo'; + + final TextField textField = tester.widget(find.byType(TextField)); + + expect( + textField.controller!.selection, + TextSelection( + baseOffset: delegate.query.length, + extentOffset: delegate.query.length, + ), + ); + }); + testWidgets('Can open and close search', (WidgetTester tester) async { final _TestSearchDelegate delegate = _TestSearchDelegate(); final List selectedResults = [];