1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | import 'package:flutter/material.dart'; |
6 | |
7 | /// Flutter code sample for [SearchAnchor.bar]. |
8 | |
9 | void main() => runApp(const SearchBarApp()); |
10 | |
11 | class SearchBarApp extends StatefulWidget { |
12 | const SearchBarApp({super.key}); |
13 | |
14 | @override |
15 | State<SearchBarApp> createState() => _SearchBarAppState(); |
16 | } |
17 | |
18 | class _SearchBarAppState extends State<SearchBarApp> { |
19 | Color? selectedColorSeed; |
20 | List<ColorLabel> searchHistory = <ColorLabel>[]; |
21 | |
22 | Iterable<Widget> getHistoryList(SearchController controller) { |
23 | return searchHistory.map( |
24 | (ColorLabel color) => ListTile( |
25 | leading: const Icon(Icons.history), |
26 | title: Text(color.label), |
27 | trailing: IconButton( |
28 | icon: const Icon(Icons.call_missed), |
29 | onPressed: () { |
30 | controller.text = color.label; |
31 | controller.selection = TextSelection.collapsed(offset: controller.text.length); |
32 | }, |
33 | ), |
34 | ), |
35 | ); |
36 | } |
37 | |
38 | Iterable<Widget> getSuggestions(SearchController controller) { |
39 | final String input = controller.value.text; |
40 | return ColorLabel.values |
41 | .where((ColorLabel color) => color.label.contains(input)) |
42 | .map( |
43 | (ColorLabel filteredColor) => ListTile( |
44 | leading: CircleAvatar(backgroundColor: filteredColor.color), |
45 | title: Text(filteredColor.label), |
46 | trailing: IconButton( |
47 | icon: const Icon(Icons.call_missed), |
48 | onPressed: () { |
49 | controller.text = filteredColor.label; |
50 | controller.selection = TextSelection.collapsed(offset: controller.text.length); |
51 | }, |
52 | ), |
53 | onTap: () { |
54 | controller.closeView(filteredColor.label); |
55 | handleSelection(filteredColor); |
56 | }, |
57 | ), |
58 | ); |
59 | } |
60 | |
61 | void handleSelection(ColorLabel selectedColor) { |
62 | setState(() { |
63 | selectedColorSeed = selectedColor.color; |
64 | if (searchHistory.length >= 5) { |
65 | searchHistory.removeLast(); |
66 | } |
67 | searchHistory.insert(0, selectedColor); |
68 | }); |
69 | } |
70 | |
71 | @override |
72 | Widget build(BuildContext context) { |
73 | final ThemeData themeData = ThemeData(colorSchemeSeed: selectedColorSeed); |
74 | final ColorScheme colors = themeData.colorScheme; |
75 | |
76 | return MaterialApp( |
77 | theme: themeData, |
78 | home: Scaffold( |
79 | appBar: AppBar(title: const Text('Search Bar Sample' )), |
80 | body: Align( |
81 | alignment: Alignment.topCenter, |
82 | child: Column( |
83 | children: <Widget>[ |
84 | SearchAnchor.bar( |
85 | barHintText: 'Search colors' , |
86 | suggestionsBuilder: (BuildContext context, SearchController controller) { |
87 | if (controller.text.isEmpty) { |
88 | if (searchHistory.isNotEmpty) { |
89 | return getHistoryList(controller); |
90 | } |
91 | return <Widget>[ |
92 | Center( |
93 | child: Text('No search history.' , style: TextStyle(color: colors.outline)), |
94 | ), |
95 | ]; |
96 | } |
97 | return getSuggestions(controller); |
98 | }, |
99 | ), |
100 | cardSize, |
101 | Card(color: colors.primary, child: cardSize), |
102 | Card(color: colors.onPrimary, child: cardSize), |
103 | Card(color: colors.primaryContainer, child: cardSize), |
104 | Card(color: colors.onPrimaryContainer, child: cardSize), |
105 | Card(color: colors.secondary, child: cardSize), |
106 | Card(color: colors.onSecondary, child: cardSize), |
107 | ], |
108 | ), |
109 | ), |
110 | ), |
111 | ); |
112 | } |
113 | } |
114 | |
115 | SizedBox cardSize = const SizedBox(width: 80, height: 30); |
116 | |
117 | enum ColorLabel { |
118 | red('red' , Colors.red), |
119 | orange('orange' , Colors.orange), |
120 | yellow('yellow' , Colors.yellow), |
121 | green('green' , Colors.green), |
122 | blue('blue' , Colors.blue), |
123 | indigo('indigo' , Colors.indigo), |
124 | violet('violet' , Color(0xFF8F00FF)), |
125 | purple('purple' , Colors.purple), |
126 | pink('pink' , Colors.pink), |
127 | silver('silver' , Color(0xFF808080)), |
128 | gold('gold' , Color(0xFFFFD700)), |
129 | beige('beige' , Color(0xFFF5F5DC)), |
130 | brown('brown' , Colors.brown), |
131 | grey('grey' , Colors.grey), |
132 | black('black' , Colors.black), |
133 | white('white' , Colors.white); |
134 | |
135 | const ColorLabel(this.label, this.color); |
136 | final String label; |
137 | final Color color; |
138 | } |
139 | |