Add a SearchAnchor example to experimental demo (#1722)

pull/1724/head
Qun Cheng 1 year ago committed by GitHub
parent 87bb622623
commit 1c127bc2c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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));

Loading…
Cancel
Save