[Fix]: Searchbar doesn't lose focus when tapped outside (#145232)

Added a Fix to search bar that allows it be unfocused when tapped anywhere outside the search bar.

I have attached below the app flow after implementing the fix.

https://github.com/flutter/flutter/assets/54017876/70915c47-9b77-4a43-a128-8706107f921f

Issue that gets resolved by this fix: #145096

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
This commit is contained in:
Sahil Kachhap 2024-03-25 22:32:07 +05:30 committed by GitHub
parent 2851ed3202
commit a9f18b803b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 47 additions and 0 deletions

View file

@ -1118,6 +1118,7 @@ class SearchBar extends StatefulWidget {
this.leading,
this.trailing,
this.onTap,
this.onTapOutside,
this.onChanged,
this.onSubmitted,
this.constraints,
@ -1170,6 +1171,9 @@ class SearchBar extends StatefulWidget {
/// Called when the user taps this search bar.
final GestureTapCallback? onTap;
/// Called when the user taps outside the search bar.
final TapRegionCallback? onTapOutside;
/// Invoked upon user input.
final ValueChanged<String>? onChanged;
@ -1397,6 +1401,7 @@ class _SearchBarState extends State<SearchBar> {
autofocus: widget.autoFocus,
onTap: widget.onTap,
onTapAlwaysCalled: true,
onTapOutside: widget.onTapOutside,
focusNode: _focusNode,
onChanged: widget.onChanged,
onSubmitted: widget.onSubmitted,

View file

@ -3061,6 +3061,48 @@ void main() {
expect(box.size.height, 32);
});
testWidgets('Tapping outside searchbar should unfocus the searchbar on mobile', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
addTearDown(focusNode.dispose);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: SearchAnchor(
builder: (BuildContext context, SearchController controller){
return SearchBar(
controller: controller,
onTap: () {
controller.openView();
},
onTapOutside: (PointerDownEvent event) {
focusNode.unfocus();
},
onChanged: (_) {
controller.openView();
},
autoFocus: true,
focusNode: focusNode,
);
},
suggestionsBuilder: (BuildContext context, SearchController controller){
return List<ListTile>.generate(5, (int index) {
final String item = 'item $index';
return ListTile(title: Text(item));
});
},
)
),
),
);
await tester.pump();
expect(focusNode.hasPrimaryFocus, isTrue);
await tester.tapAt(const Offset(50, 50));
await tester.pump();
expect(focusNode.hasPrimaryFocus, isFalse);
}, variant: TargetPlatformVariant.mobile());
testWidgets('The default clear button only shows when text input is not empty '
'on the search view', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(