There are a lot of tutorials but rather than help me to move forward, I get lost in all possible options or I don't know how to improve the code (I would like to use an application that displays a list that use more than only the name of three fruits or three cities ?)
I found tutorials to create a nice SearchBar with the ability to display the result based on the first letters typed.
I don't understand how to edit the tutorial with a data list that includes a title associated with the content. I don't understand how to display the result if the first letter is lowercase or uppercase. Would it be possible to help me to make a simple basic code that could serve everyone including beginners like me?
DataList.dart
List<ListWords> listWords = [
ListWords('oneWord', 'OneWord definition'),
ListWords('twoWord', 'TwoWord definition.'),
ListWords('TreeWord', 'TreeWord definition'),
];
class ListWords {
String titlelist;
String definitionlist;
ListWords(String titlelist, String definitionlist) {
this.titlelist = titlelist;
this.definitionlist = definitionlist;
}
}
Searchbar.dart
import 'package:flutter/material.dart';
import 'package:test_searchbar/DataList.dart';
class SearchBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Search App'),
actions: <Widget>[
IconButton(icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch(listWords));
})
],
),
drawer: Drawer(),
);
}
}
class DataSearch extends SearchDelegate<String> {
final List<ListWords> listWords;
DataSearch(this.listWords);
@override
List<Widget> buildActions(BuildContext context) {
//Actions for app bar
return [IconButton(icon: Icon(Icons.clear), onPressed: () {
query = '';
})];
}
@override
Widget buildLeading(BuildContext context) {
//leading icon on the left of the app bar
return IconButton(
icon: AnimatedIcon(icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
@override
Widget buildResults(BuildContext context) {
// show some result based on the selection
return Center(
child: Text(query),
);
}
@override
Widget buildSuggestions(BuildContext context) {
// show when someone searches for something
final suggestionList = query.isEmpty
? listWords
: listWords.where((p) => p.startsWith(query)).toList();
return ListView.builder(itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context);
},
trailing: Icon(Icons.remove_red_eye),
title: RichText(
text: TextSpan(
text: suggestionList[index].titlelist.substring(0, query.length),
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: suggestionList[index].titlelist.substring(query.length),
style: TextStyle(color: Colors.grey))
]),
),
),
itemCount: suggestionList.length,
);
}
}
To create a search appbar, you will need a stateful widget with the following code,
Inside your State class,
TextEditingController _searchQueryController = TextEditingController();
bool _isSearching = false;
String searchQuery = "Search query";
Inside Scaffold, your appbar should be like,
appBar: AppBar(
leading: _isSearching ? const BackButton() : Container(),
title: _isSearching ? _buildSearchField() : _buildTitle(context),
actions: _buildActions(),
),
Define the required following methods for displaying and managing searchbar,
Widget _buildSearchField() {
return TextField(
controller: _searchQueryController,
autofocus: true,
decoration: InputDecoration(
hintText: "Search Data...",
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.white30),
),
style: TextStyle(color: Colors.white, fontSize: 16.0),
onChanged: (query) => updateSearchQuery(query),
);
}
List<Widget> _buildActions() {
if (_isSearching) {
return <Widget>[
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
if (_searchQueryController == null ||
_searchQueryController.text.isEmpty) {
Navigator.pop(context);
return;
}
_clearSearchQuery();
},
),
];
}
return <Widget>[
IconButton(
icon: const Icon(Icons.search),
onPressed: _startSearch,
),
];
}
void _startSearch() {
ModalRoute.of(context)
.addLocalHistoryEntry(LocalHistoryEntry(onRemove: _stopSearching));
setState(() {
_isSearching = true;
});
}
void updateSearchQuery(String newQuery) {
setState(() {
searchQuery = newQuery;
});
}
void _stopSearching() {
_clearSearchQuery();
setState(() {
_isSearching = false;
});
}
void _clearSearchQuery() {
setState(() {
_searchQueryController.clear();
updateSearchQuery("");
});
}
This is the best way to implement an app searchbar in any flutter screen.
Finally, I managed to do this. This is a good starting point for the Search Show in a list. Does this are correct?
DataList.dart
List<ListWords> listWords = [
ListWords('oneWord', 'OneWord definition'),
ListWords('twoWord', 'TwoWord definition.'),
ListWords('TreeWord', 'TreeWord definition'),
];
class ListWords {
String titlelist;
String definitionlist;
ListWords(String titlelist, String definitionlist) {
this.titlelist = titlelist;
this.definitionlist = definitionlist;
}
}
SearchBar.dart
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:test_searchbar/DataList.dart';
import 'package:test_searchbar/detail.dart';
class SearchBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Search App'),
actions: <Widget>[
IconButton(icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch(listWords));
})
],
),
body: Center(
child: Text('default content')
),
drawer: Drawer(),
);
}
}
class DataSearch extends SearchDelegate<String> {
final List<ListWords> listWords;
DataSearch(this.listWords);
@override
List<Widget> buildActions(BuildContext context) {
//Actions for app bar
return [IconButton(icon: Icon(Icons.clear), onPressed: () {
query = '';
})];
}
@override
Widget buildLeading(BuildContext context) {
//leading icon on the left of the app bar
return IconButton(
icon: AnimatedIcon(icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
@override
Widget buildResults(BuildContext context) {
// show some result based on the selection
final suggestionList = listWords;
return ListView.builder(itemBuilder: (context, index) => ListTile(
title: Text(listWords[index].titlelist),
subtitle: Text(listWords[index].definitionlist),
),
itemCount: suggestionList.length,
);
}
@override
Widget buildSuggestions(BuildContext context) {
// show when someone searches for something
final suggestionList = query.isEmpty
? listWords
: listWords.where((p) => p.titlelist.contains(RegExp(query, caseSensitive: false))).toList();
return ListView.builder(itemBuilder: (context, index) => ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detail(listWordsDetail: suggestionList[index]),
),
);
},
trailing: Icon(Icons.remove_red_eye),
title: RichText(
text: TextSpan(
text: suggestionList[index].titlelist.substring(0, query.length),
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: suggestionList[index].titlelist.substring(query.length),
style: TextStyle(color: Colors.grey)),
]),
),
),
itemCount: suggestionList.length,
);
}
}
detail.dart
import 'package:flutter/material.dart';
import 'package:test_searchbar/DataList.dart';
class Detail extends StatelessWidget {
final ListWords listWordsDetail;
Detail({Key key, @required this.listWordsDetail}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
brightness: Brightness.dark,
title: const Text('Détail', style: TextStyle(color: Colors.white)),
iconTheme: IconThemeData(color: Colors.white),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(listWordsDetail.titlelist +' (on detail page)'),
Text(listWordsDetail.definitionlist),
],
),
)
);
}
}
It would be best if the return from the detail page opens the Searchbar page with the default content and the closed searchbar ...
There is a ready to use widget for this:
appBar: AppBarWithSearchSwitch(
onChanged: (text) {
searchText.value = text;
}, // or use: onSubmitted: (text) => searchText.value = text,
appBarBuilder: (context) {
return AppBar(
title: Text('Example '),
actions: [
AppBarSearchButton(), // button to activate search
],
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With