mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 13:58:47 +00:00
Add a SearchAnchor example to experimental demo (#1722)
This commit is contained in:
@@ -140,8 +140,8 @@ class Navigation extends StatelessWidget {
|
||||
),
|
||||
NavigationDrawers(scaffoldKey: scaffoldKey),
|
||||
const NavigationRails(),
|
||||
// TODO: Add Search https://github.com/flutter/flutter/issues/117483
|
||||
const Tabs(),
|
||||
const SearchAnchors(),
|
||||
const TopAppBars(),
|
||||
]);
|
||||
}
|
||||
@@ -2182,6 +2182,101 @@ class _SlidersState extends State<Sliders> {
|
||||
}
|
||||
}
|
||||
|
||||
class SearchAnchors extends StatefulWidget {
|
||||
const SearchAnchors({super.key});
|
||||
|
||||
@override
|
||||
State<SearchAnchors> createState() => _SearchAnchorsState();
|
||||
}
|
||||
|
||||
class _SearchAnchorsState extends State<SearchAnchors> {
|
||||
String? selectedColor;
|
||||
List<ColorItem> searchHistory = <ColorItem>[];
|
||||
|
||||
Iterable<Widget> getHistoryList(SearchController controller) {
|
||||
return searchHistory.map((color) => ListTile(
|
||||
leading: const Icon(Icons.history),
|
||||
title: Text(color.label),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.call_missed),
|
||||
onPressed: () {
|
||||
controller.text = color.label;
|
||||
controller.selection =
|
||||
TextSelection.collapsed(offset: controller.text.length);
|
||||
}),
|
||||
onTap: () {
|
||||
controller.closeView(color.label);
|
||||
handleSelection(color);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
Iterable<Widget> getSuggestions(SearchController controller) {
|
||||
final String input = controller.value.text;
|
||||
return ColorItem.values
|
||||
.where((color) => color.label.contains(input))
|
||||
.map((filteredColor) => ListTile(
|
||||
leading: CircleAvatar(backgroundColor: filteredColor.color),
|
||||
title: Text(filteredColor.label),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.call_missed),
|
||||
onPressed: () {
|
||||
controller.text = filteredColor.label;
|
||||
controller.selection =
|
||||
TextSelection.collapsed(offset: controller.text.length);
|
||||
}),
|
||||
onTap: () {
|
||||
controller.closeView(filteredColor.label);
|
||||
handleSelection(filteredColor);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
void handleSelection(ColorItem color) {
|
||||
setState(() {
|
||||
selectedColor = color.label;
|
||||
if (searchHistory.length >= 5) {
|
||||
searchHistory.removeLast();
|
||||
}
|
||||
searchHistory.insert(0, color);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ComponentDecoration(
|
||||
label: 'Search',
|
||||
tooltipMessage: 'Use SearchAnchor or SearchAnchor.bar',
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SearchAnchor.bar(
|
||||
barHintText: 'Search colors',
|
||||
suggestionsBuilder: (context, controller) {
|
||||
if (controller.text.isEmpty) {
|
||||
if (searchHistory.isNotEmpty) {
|
||||
return getHistoryList(controller);
|
||||
}
|
||||
return <Widget>[
|
||||
const Center(
|
||||
child: Text('No search history.',
|
||||
style: TextStyle(color: Colors.grey)),
|
||||
)
|
||||
];
|
||||
}
|
||||
return getSuggestions(controller);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if (selectedColor == null)
|
||||
const Text('Select a color')
|
||||
else
|
||||
Text('Last selected color is $selectedColor')
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ComponentDecoration extends StatefulWidget {
|
||||
const ComponentDecoration({
|
||||
super.key,
|
||||
@@ -2291,3 +2386,26 @@ class ComponentGroupDecoration extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum ColorItem {
|
||||
red('red', Colors.red),
|
||||
orange('orange', Colors.orange),
|
||||
yellow('yellow', Colors.yellow),
|
||||
green('green', Colors.green),
|
||||
blue('blue', Colors.blue),
|
||||
indigo('indigo', Colors.indigo),
|
||||
violet('violet', Color(0xFF8F00FF)),
|
||||
purple('purple', Colors.purple),
|
||||
pink('pink', Colors.pink),
|
||||
silver('silver', Color(0xFF808080)),
|
||||
gold('gold', Color(0xFFFFD700)),
|
||||
beige('beige', Color(0xFFF5F5DC)),
|
||||
brown('brown', Colors.brown),
|
||||
grey('grey', Colors.grey),
|
||||
black('black', Colors.black),
|
||||
white('white', Colors.white);
|
||||
|
||||
const ColorItem(this.label, this.color);
|
||||
final String label;
|
||||
final Color color;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,9 @@ void main() {
|
||||
// Tabs
|
||||
expect(find.byType(TabBar), findsOneWidget);
|
||||
|
||||
// Search
|
||||
expect(find.byType(SearchBar), findsOneWidget);
|
||||
|
||||
// Top app bars
|
||||
expect(find.byType(AppBar), findsNWidgets(6));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user