How to navigate to a new page from search results - flutter

I am trying to find out about search navigation and could not find any suitable tutorial showing me how to navigate to specific pages after your search. I hope someone could explain me how I can do this.
After searching "Google" I would like to press on it and be redirected to a new page through navigation.
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
#override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
Widget appBarTitle = Text(
"Search",
style: TextStyle(color: Colors.white),
);
Icon actionIcon = Icon(
Icons.search,
color: Colors.white,
);
final key = GlobalKey<ScaffoldState>();
final TextEditingController _searchQuery = TextEditingController();
List<String> _list;
bool _isSearching;
String _searchText = "";
_SearchPageState() {
_searchQuery.addListener(() {
if (_searchQuery.text.isEmpty) {
setState(() {
_isSearching = false;
_searchText = "";
});
} else {
setState(() {
_isSearching = true;
_searchText = _searchQuery.text;
});
}
});
}
#override
void initState() {
super.initState();
_isSearching = false;
initData();
}
void initData() {
_list = List();
_list.add("google");
_list.add("IOS");
_list.add("Android");
_list.add("Linux");
_list.add("MacOS");
_list.add("Windows");
}
#override
Widget build(BuildContext context) {
return new Scaffold(
key: key,
appBar: buildBar(context),
body: new ListView(
padding: new EdgeInsets.symmetric(vertical: 8.0),
children: _isSearching ? _buildSearchList() : _buildList(),
),
);
}
List<ChildItem> _buildList() {
return _list.map((contact) => new ChildItem(contact)).toList();
}
List<ChildItem> _buildSearchList() {
if (_searchText.isEmpty) {
return _list.map((contact) => new ChildItem(contact))
.toList();
}
else {
List<String> _searchList = List();
for (int i = 0; i < _list.length; i++) {
String name = _list.elementAt(i);
if (name.toLowerCase().contains(_searchText.toLowerCase())) {
_searchList.add(name);
}
}
return _searchList.map((contact) => new ChildItem(contact))
.toList();
}
}
Widget buildBar(BuildContext context) {
return new AppBar(
centerTitle: true,
title: appBarTitle,
actions: <Widget>[
new IconButton(icon: actionIcon, onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close, color: Colors.white,);
this.appBarTitle = new TextField(
controller: _searchQuery,
style: new TextStyle(
color: Colors.white,
),
decoration: new InputDecoration(
prefixIcon: new Icon(Icons.search, color: Colors.white),
hintText: "search...",
hintStyle: new TextStyle(color: Colors.white)
),
);
_handleSearchStart();
}
else {
_handleSearchEnd();
}
});
},),
]
);
}
void _handleSearchStart() {
setState(() {
_isSearching = true;
});
}
void _handleSearchEnd() {
setState(() {
this.actionIcon = new Icon(Icons.search, color: Colors.white,);
this.appBarTitle =
new Text("search", style: new TextStyle(color: Colors.white),);
_isSearching = false;
_searchQuery.clear();
});
}
}
class ChildItem extends StatelessWidget {
final String name;
ChildItem(this.name);
#override
Widget build(BuildContext context) {
return new ListTile(title: new Text(this.name));
}
}

You can also do it with a SearchDelegate.
Query and navigation under the buildSuggestions.
#override
Widget buildSuggestions(BuildContext context) {
final suggestionsList = query.isEmpty
? myList
: myList
.where((p) => p.toLowerCase().contains(query.toLowerCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
close(context, suggestionsList[index]);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index]))));
},
title: Text(suggestionsList[index]),
),
itemCount: suggestionsList.length,
);
}
The important part is pairing yourList's index with suggestionList index :
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index])))
Below is all the code with navigation.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Search Example"),
actions: [
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: SearchItem());
}),
],
),
);
}
}
final List<String> myList = [
"google",
"IOS",
"Android",
"Linux",
"MacOS",
"Windows"
];
class SearchItem extends SearchDelegate<String> {
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
})
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
#override
Widget buildResults(BuildContext context) {}
#override
Widget buildSuggestions(BuildContext context) {
final suggestionsList = query.isEmpty
? myList
: myList
.where((p) => p.toLowerCase().contains(query.toLowerCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
close(context, suggestionsList[index]);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index]))));
},
title: Text(suggestionsList[index]),
),
itemCount: suggestionsList.length,
);
}
}
class DetailScreen extends StatelessWidget {
final int index;
DetailScreen(this.index);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("${myList[index]}"),),
body: Center(
child: Text(
"${myList[index]}",style: TextStyle(fontSize: 22),
),
));
}
}

Related

setState() not updating UI elements even though the state variable, a Future, is updated?

I have a HomePage screen which has a FutureBuilder List implemented with a Future function as the state variable. I am updating this Future in another dart file by using keys to access the future. The Future gets updated and I'm sure of this as I've seen the print statements, but when I call the setState method, the UI doesn't show the newly added entry.
Here's my HomePage.dart:
class HomePage extends StatefulWidget {
const HomePage({super.key});
#override
State<HomePage> createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
Future<List<Model>> getData() async {
return await DatabaseHelper.instance.getModels();
}
Future? userFuture;
#override
void initState() {
super.initState();
userFuture = getData();
print(userFuture);
}
#override
Widget build(BuildContext context) {
print('Building listview');
return Center(
child: FutureBuilder<List<Model>>(
future: userFuture as Future<List<Model>>,
builder: ((context, AsyncSnapshot<List<Model>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const CircularProgressIndicator();
default:
if (snapshot.data!.isEmpty) {
return Text('No data present');
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: ((context, index) {
return MyCard(
key: ValueKey(snapshot.data![index].id),
snapshot.data![index].id,
snapshot.data![index].title,
snapshot.data![index].purpose);
}),
);
}
return Text('data');
}
}),
),
);
}
}
Here's my other dart file. Under the AddEntryState I'm updating the Future state variable and then right after calling the setState method.
class RootPage extends StatefulWidget {
const RootPage({super.key});
#override
State<RootPage> createState() => RootPageState();
}
class RootPageState extends State<RootPage> {
static final GlobalKey<HomePageState> homepageKey =
GlobalKey<HomePageState>();
int currentPage = 0;
List<Widget>? pages;
#override
void initState() {
super.initState();
pages = [
HomePage(key: homepageKey),
StatsPage(),
];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('App Title'),
),
body: pages?[currentPage],
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => AddEntry()));
},
child: Icon(Icons.add),
),
bottomNavigationBar: NavigationBar(
destinations: [
NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
NavigationDestination(icon: Icon(Icons.data_usage), label: 'Stats'),
],
onDestinationSelected: (int index) {
setState(() {
currentPage = index;
print(index);
});
},
selectedIndex: currentPage,
),
);
}
}
class AddEntry extends StatefulWidget {
const AddEntry({super.key});
#override
State<AddEntry> createState() => _AddEntryState();
}
class _AddEntryState extends State<AddEntry> {
final GlobalKey<FormState> _key = GlobalKey<FormState>();
Map<String, String?> formField = <String, String?>{};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('New Entry'),
),
body: Form(
key: _key,
child: Column(
children: [
Flexible(
child: MyTextField('Title', callback),
),
Flexible(
child: MyTextField('Purpose', callback),
),
Flexible(
child: MyTextField('Password', callback, obscure: true),
),
TextButton(
onPressed: () async {
if (_key.currentState!.validate()) {
_key.currentState?.save();
formField.forEach((label, value) => print('$label = $value'));
await DatabaseHelper.instance.insertModel(Model(
id: null,
title: formField['Title'],
purpose: formField['Purpose'],
lastAccess: DateTime.now().toString(),
dateAdded: DateTime.now().toString(),
password: formField['Password']));
print(await DatabaseHelper.instance.getModels());
// await DatabaseHelper.instance.deleteAllData();
// print(await DatabaseHelper.instance.getModels());
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Data Saved!'),
action: SnackBarAction(
label: 'Edit',
onPressed: () {
print('edit pressed!');
},
),
),
);
Navigator.pop(context);
print("HomePage userFuture: ");
print(RootPageState.homepageKey.currentState!.userFuture!
.then((result) => print(result)));
print("getData function: ");
print(RootPageState.homepageKey.currentState!
.getData()
.then((result) => print(result)));
print("New Future: ");
print(RootPageState.homepageKey.currentState!.userFuture!
.then((result) => print(result)));
setState(() {
RootPageState.homepageKey.currentState!.userFuture =
RootPageState.homepageKey.currentState!.getData();
});
//add logic to rebuild home screen after every addition of entry
}
},
child: Text('Submit'),
),
],
),
),
);
}
callback(varLabel, varValue) {
formField[varLabel] = varValue;
}
}

Flutter: How to select multiple options in checkboxlisttile

class PickLabelScreen extends StatefulWidget {
const PickLabelScreen({
Key? key,
required this.labelTitle,
}) : super(key: key);
final String labelTitle;
#override
State<PickLabelScreen> createState() => _PickLabelScreenState();
}
class _PickLabelScreenState extends State<PickLabelScreen> {
late String _labelChoosed;
#override
void initState() {
super.initState();
_labelChoosed = widget.labelTitle;
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
Navigator.of(context).pop(_labelChoosed);
return false;
},
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
),
onPressed: () {
Navigator.of(context).pop(_labelChoosed);
},
),
actions: [
IconButton(
onPressed: () async {
final String newLabel = await showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const DialogLabelWidget(),
);
setState(() {
if (newLabel.isNotEmpty) _labelChoosed = newLabel;
});
},
icon: const Icon(Icons.add),
),
],
),
body: Consumer<LabelProvider>(
builder: (context, labelProvider, child) =>
labelProvider.items.isEmpty
? child!
: ListView.builder(
itemBuilder: (context, index) {
final currentLabel = labelProvider.items[index];
return CheckboxListTile(
value: _labelChoosed == currentLabel.title,
title: Text(
currentLabel.title,
style: TextStyleConstants.titleStyle3,
),
secondary: const Icon(Icons.label_outline),
onChanged: (value) {
setState(() {
if (value == true) {
_labelChoosed = currentLabel.title;
} else {
_labelChoosed = '';
}
});
},
activeColor: ColorsConstant.blueColor,
);
},
itemCount: labelProvider.items.length,
),
child: const SizedBox.shrink(),
),
),
);
}
}
This is a flutter note app, and I am trying to label the notes.
Can anyone tell me how to select several options to label notes?
This code can create multiple options with dialoge, but cannot click them at once.
What I want is to create, select more than one checkbox, and save them to database.
Here is pick_label_screen.dart code.

showSearch with API

I am trying to implement the search feature and want to get the results from the API.
Under the method buildResults() you will find my comment // data is null but the problem is that I am getting data from the API call. Am I missing something here?
Under buildsResults() I am calling the Future _getResults and returning the received data. I logged the data which you can see.
class SearchBar extends StatefulWidget {
#override
_SearchBarState createState() => new _SearchBarState();
}
class _SearchBarState extends State<SearchBar> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: new IconThemeData(color: Theme.of(context).hintColor),
elevation: 1,
backgroundColor: Theme.of(context).primaryColor,
actions: <Widget>[
IconButton(
autofocus: true,
icon: Icon(Icons.search),
onPressed: () async {
final results = await showSearch<SearchModel>(context: context, delegate: DataSearch(context));
})
],
centerTitle: true,
title: Text('Search content'),
),
);
}
}
class DataSearch extends SearchDelegate<SearchModel> {
final BuildContext parentContext;
final Logger logger = new Logger();
DataSearch(this.parentContext);
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
},
)
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
Navigator.pop(context);
Navigator.pop(parentContext);
},
);
}
#override
Widget buildResults(BuildContext context) {
return FutureBuilder<List<SearchModel>>(
future: _getResults(),
builder: (context, AsyncSnapshot<List<SearchModel>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
logger.d(snapshot.hasData);
return ListView.builder(
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data[index].title),
onTap: () {
close(context, snapshot.data[index]);
},
);
},
itemCount: snapshot.data.length, // data is null
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
);
}
#override
Widget buildSuggestions(BuildContext context) {
return Container();
}
Future<List<SearchModel>> _getResults() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String language = prefs.getString('language');
var data;
await http.get(Constants.BASE_URL + "/search/" + language + "/" + query,).then((response) {
data = convert.jsonDecode(response.body) as List;
});
logger.d(data);
return data.map((model) => SearchModel.fromJson(model)).toList();
}
}
I think that's how it works:
onTap: () async {
final results = await showSearch(context: context, delegate: SearchBar(),query:query);
}
Result gets the return value
Query is the argument passed

Provider works in child but not in SearchDelegate

This is the error:
Error: Could not find the correct Provider<List<ListTile>> above this Widget
I have an app that displays items from a FutureProvider. I use the provider twice, one at the end to generate a ListView in the same page using ListaProductos(), and one at the AppBar to generate the same ListView on a SearchDelegate.
This is the main page:
#override
Widget build(BuildContext context) {
if (user != null) {
return FutureProvider<List<ListTile>>.value(
value:
ServicioBaseDatos(usuarioUID: user.uid).listaProductos,
child: new Scaffold(
appBar: AppBar(
title: Text(
"Stock",
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
var listaProductos = Provider.of<List<ListTile>>(context);
showSearch(
context: context,
delegate: SearchProducto(listaProductos),
);
},
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.of(context).push(new MaterialPageRoute(
builder: (BuildContext context) => new CrearProductoPage())),
child: Icon(
Icons.add,
),
),
drawer: MenuComponent(user.email == null ? '' : user.email),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFFAE885E), Color(0xFF557A95)])),
child: ListaProductos()),
),
);
} else {
return Text('Esperando identificador de usuario de la base de datos');
}
}
This is the ListaProductos() widget (works fine):
class ListaProductos extends StatefulWidget {
#override
_ListaProductosState createState() => _ListaProductosState();
}
class _ListaProductosState extends State<ListaProductos> {
#override
Widget build(BuildContext context) {
final productos = Provider.of<List<ListTile>>(context);
if (productos != null){
return ListView.builder(
itemCount: productos.length,
itemBuilder: (context, index) {
return productos[index];
},
);
}
else {return Text('Esperando respuesta de base de datos');}
}
}
This is the SearchDelegate implementation (The error appears when I click at the search icon that opens this page):
class SearchProducto extends SearchDelegate<ListTile> {
final List<ListTile> listaProductos;
SearchProducto(this.listaProductos);
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = '';
},
),
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
return Container();
}
#override
Widget buildSuggestions(BuildContext context) {
if (listaProductos != null){
return ListView.builder(
itemCount: listaProductos.length,
itemBuilder: (context, index) {
return listaProductos[index];
},
);
}
else {return Text('Esperando respuesta de BD');}
}
}
I'm halfway a Boring show but they don't use Provider. Ideas? Thanks for your help!
Edit: This is the value: of the FutureProvider:
Future<List<ListTile>> get listaProductos async {
List<ListTile> listaProd = [];
final documentos = await colecUsuario
.document(usuarioUID)
.collection('ListaItems')
.getDocuments();
if (documentos != null) {
for (var doc in documentos.documents) {
for (var k in doc.data.keys) {
listaProd.add(
ListTile(
title: Text(k),
trailing: Text(doc.data[k].toString()),
)
);
}
}
}
return listaProd;
}
intentaste obtener la información dentro del Search en vez de pasarlo ?
class SearchProducto extends SearchDelegate<ListTile> {
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = '';
},
),
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
return Container();
}
#override
Widget buildSuggestions(BuildContext context) {
final listaProductos = Provider.of<List<ListTile>>(context);
if (listaProductos != null){
return ListView.builder(
itemCount: listaProductos.length,
itemBuilder: (context, index) {
return listaProductos[index];
},
);
}
else {return Text('Esperando respuesta de BD');}
}
}

Passing data between screen

I'm new to flutter and I want to passe some data between screens.
I know a simular question was ask here but I try that solution but for my code did not work.
I try: "Passing data between screens in Flutter"
Search bar code:
import 'package:flutter/material.dart';
import 'Screen_4.dart';
class SearchList extends StatefulWidget {
SearchList({Key key}) : super(key: key);
#override
_SearchListState createState() => _SearchListState();
}
class _SearchListState extends State<SearchList> {
Widget appBarTitle = Text(
"Search ",
style: TextStyle(color: Colors.white),
);
Icon actionIcon = Icon(
Icons.search,
color: Colors.white,
);
final key = GlobalKey<ScaffoldState>();
final TextEditingController _searchQuery = TextEditingController();
List<String> _list;
bool _IsSearching;
String _searchText = "";
_SearchListState() {
_searchQuery.addListener(() {
if (_searchQuery.text.isEmpty) {
setState(() {
_IsSearching = false;
_searchText = "";
});
} else {
setState(() {
_IsSearching = true;
_searchText = _searchQuery.text;
});
}
});
}
#override
void initState() {
super.initState();
_IsSearching = false;
init();
}
void init() {
_list = List();
_list.add("Google");
_list.add("IOS");
_list.add("Andorid");
_list.add("Dart");
_list.add("Flutter");
_list.add("Python");
_list.add("React");
_list.add("Xamarin");
_list.add("Kotlin");
_list.add("Java");
_list.add("RxAndroid");
_list.add('Lenovo');
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: key,
appBar: buildBar(context),
body: ListView(
padding: EdgeInsets.symmetric(vertical: 8.0),
children: _IsSearching ? _buildSearchList() : _buildList(),
),
);
}
List<ChildItem> _buildList() {
return _list.map((contact) => ChildItem(contact)).toList();
}
List<ChildItem> _buildSearchList() {
if (_searchText.isEmpty) {
return _list.map((contact) => ChildItem(contact)).toList();
} else {
List<String> _searchList = List();
for (int i = 0; i < _list.length; i++) {
String name = _list.elementAt(i);
if (name.toLowerCase().contains(_searchText.toLowerCase())) {
_searchList.add(name);
}
}
return _searchList.map((contact) => ChildItem(contact)).toList();
}
}
Widget buildBar(BuildContext context) {
return AppBar(centerTitle: true, title: appBarTitle, actions: <Widget>[
IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = Icon(
Icons.close,
color: Colors.white,
);
this.appBarTitle = TextField(
controller: _searchQuery,
style: TextStyle(
color: Colors.white,
),
decoration: InputDecoration(
prefixIcon: Icon(Icons.search, color: Colors.black),
hintText: "Search...",
hintStyle: TextStyle(color: Colors.white)),
);
_handleSearchStart();
} else {
_handleSearchEnd();
}
});
},
),
]);
}
void _handleSearchStart() {
setState(() {
_IsSearching = true;
});
}
void _handleSearchEnd() {
setState(() {
this.actionIcon = Icon(
Icons.search,
color: Colors.white,
);
this.appBarTitle = Text(
"Search Sample",
style: TextStyle(color: Colors.white),
);
_IsSearching = false;
_searchQuery.clear();
});
}
}
class ChildItem extends StatelessWidget {
final String name;
ChildItem(this.name);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(this.name), //onTap: () => print(name));
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => ShowData()));
},
);
}
}
The screen I want to to show the result:
import 'search_bar_no_API.dart';
class ShowData extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text('The Name Here'),
),
What I want is the person to :
eg:
search: google
press: the name google
then go to other page with the name Google on the appbar.
In your ChildItem class do this:
class ChildItem extends StatelessWidget {
final String name;
ChildItem(this.name);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(this.name), //onTap: () => print(name));
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => ShowData(title: this.name)));
},
);
}
}
you will notice, I passed in this.name to the property title of the ShowData class in the Navigator.push(...)
and so in your ShowData class, create a final variable of type String eg. final String title and create a Constructor of the class ShowData like this ShowData({this.title}). Below is a complete code of how the ShowDataclass should look like:
class ShowData extends StatelessWidget {
final String title;
ShowData({this.title});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text(title),
)
);
}
}