Unverified Commit 6e851134 authored by Qun Cheng's avatar Qun Cheng Committed by GitHub

Add an example for SearchBar (#124992)

This PR is to: 
* Update API doc for `SearchBar`.
* Add an example to show how to use a `SearchBar` as the builder of the `SearchAnchor`.
parent cc9ffd3f
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
/// Flutter code sample for [SearchBar].
void main() => runApp(const SearchBarApp());
class SearchBarApp extends StatefulWidget {
const SearchBarApp({super.key});
@override
State<SearchBarApp> createState() => _SearchBarAppState();
}
class _SearchBarAppState extends State<SearchBarApp> {
bool isDark = false;
@override
Widget build(BuildContext context) {
final ThemeData themeData = ThemeData(useMaterial3: true, brightness: isDark ? Brightness.dark : Brightness.light);
return MaterialApp(
theme: themeData,
home: Scaffold(
appBar: AppBar(title: const Text('Search Bar Sample')),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: SearchAnchor(
builder: (BuildContext context, SearchController controller) {
return SearchBar(
controller: controller,
padding: const MaterialStatePropertyAll<EdgeInsets>(EdgeInsets.symmetric(horizontal: 16.0)),
onTap: () { controller.openView(); },
onChanged: (_) { controller.openView(); },
leading: const Icon(Icons.search),
trailing: <Widget>[
Tooltip(
message: 'Change brightness mode',
child: IconButton(
isSelected: isDark,
onPressed: () {
setState(() {
isDark = !isDark;
});
},
icon: const Icon(Icons.wb_sunny_outlined),
selectedIcon: const Icon(Icons.brightness_2_outlined),
),
)
],
);
},
suggestionsBuilder: (BuildContext context, SearchController controller) {
return List<ListTile>.generate(5, (int index) {
final String item = 'item $index';
return ListTile(
title: Text(item),
onTap: () {
setState(() {
controller.closeView(item);
});
},
);
});
}),
),
),
);
}
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter_api_samples/material/search_anchor/search_bar.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Can open search view', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SearchBarApp(),
);
final Finder searchBarFinder = find.byType(SearchBar);
final SearchBar searchBar = tester.widget<SearchBar>(searchBarFinder);
expect(find.byIcon(Icons.search), findsOneWidget);
expect(searchBar.trailing, isNotEmpty);
expect(searchBar.trailing?.length, equals(1));
final Finder trailingButtonFinder = find.widgetWithIcon(IconButton, Icons.wb_sunny_outlined);
expect(trailingButtonFinder, findsOneWidget);
await tester.tap(trailingButtonFinder);
await tester.pumpAndSettle();
expect(find.widgetWithIcon(IconButton, Icons.brightness_2_outlined), findsOneWidget);
await tester.tap(searchBarFinder);
await tester.pumpAndSettle();
expect(find.text('item 0'), findsOneWidget);
expect(find.text('item 1'), findsOneWidget);
expect(find.text('item 2'), findsOneWidget);
expect(find.text('item 3'), findsOneWidget);
expect(find.text('item 4'), findsOneWidget);
});
}
......@@ -970,9 +970,13 @@ class SearchController extends TextEditingController {
/// A Material Design search bar.
///
/// Search bars include a [leading] Search icon, a text input field and optional
/// [trailing] icons. A search bar is typically used to open a search view.
/// It is the default trigger for a search view.
/// A [SearchBar] looks like a [TextField]. Tapping a SearchBar typically shows a
/// "search view" route: a route with the search bar at the top and a list of
/// suggested completions for the search bar's text below. [SearchBar]s are
/// usually created by a [SearchAnchor.builder]. The builder provides a
/// [SearchController] that's used by the search bar's [SearchBar.onTap] or
/// [SearchBar.onChanged] callbacks to show the search view and to hide it
/// when the user selects a suggestion.
///
/// For [TextDirection.ltr], the [leading] widget is on the left side of the bar.
/// It should contain either a navigational action (such as a menu or up-arrow)
......@@ -982,6 +986,21 @@ class SearchController extends TextEditingController {
/// the search bar. Typically only one or two action icons are included.
/// These actions can represent additional modes of searching (like voice search),
/// a separate high-level action (such as current location) or an overflow menu.
///
/// {@tool dartpad}
/// This example demonstrates how to use a [SearchBar] as the return value of the
/// [SearchAnchor.builder] property. The [SearchBar] also includes a leading search
/// icon and a trailing action to toggle the brightness.
///
/// ** See code in examples/api/lib/material/search_anchor/search_bar.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [SearchAnchor], a widget that typically uses an [IconButton] or a [SearchBar]
/// to manage a "search view" route.
/// * [SearchBarTheme], a widget that overrides the default configuration of a search bar.
/// * [SearchViewTheme], a widget that overrides the default configuration of a search view.
class SearchBar extends StatefulWidget {
/// Creates a Material Design search bar.
const SearchBar({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment