Boolean always turn into 'False', spontaneously - flutter

I'm building 'What to Do list' app,
I made my own class Bucket(String, String, bool).
3rd property bool plays a role in checking if this task has done.
I designed if bool is false, unfulfilled task get fontweight.bold and icon is shown red, and if bool is true, fulfilled task get fontweight.normal and icons is shown green.
But, as soon as bool get 'true', it turns in to 'false', spontaneously.
No other codes are designed to get bool changed.
I don't understand why :(
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Homepage(),
);
}
}
class Homepage extends StatefulWidget {
Homepage({Key? key}) : super(key: key);
#override
State<Homepage> createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('WhattoDo List')),
floatingActionButton: IconButton(
onPressed: () async {
Bucket newbucket = await Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => PopUp()));
setState(() {
bucketlist.add(newbucket);
});
},
icon: Icon(Icons.add)),
body: bucketlist.isEmpty
? Center(child: Text('List is empty'))
: ListView.builder(
itemCount: bucketlist.length,
itemBuilder: (BuildContext context, int index) {
bool donecheck = bucketlist[index].isDone;
print(donecheck);
return Container(
margin: EdgeInsets.only(top: 5),
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.teal[200],
borderRadius: BorderRadius.circular(8)),
child: ListTile(
title: Text(
bucketlist[index].whattodo,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
decoration: donecheck
? TextDecoration.lineThrough
: TextDecoration.none),
),
subtitle: Text(
bucketlist[index].deadline,
style: TextStyle(fontSize: 15),
),
trailing: IconButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Wanna remove?"),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Cancel"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
setState(() {
bucketlist.removeAt(index);
});
},
child: Text(
"OK",
style: TextStyle(color: Colors.pink),
),
),
],
);
},
);
},
icon: Icon(Icons.delete)),
leading: IconButton(
onPressed: () {
setState(() {
donecheck = !donecheck;
print(donecheck);
});
},
icon: Icon(
Icons.check,
color: donecheck ? Colors.green : Colors.red,
)),
));
}));
}
}
class Bucket {
String whattodo;
String deadline;
bool isDone;
Bucket(this.whattodo, this.deadline, this.isDone);
}
List<Bucket> bucketlist = [];
class PopUp extends StatefulWidget {
const PopUp({Key? key}) : super(key: key);
#override
State<PopUp> createState() => _PopUpState();
}
class _PopUpState extends State<PopUp> {
TextEditingController textController = TextEditingController();
TextEditingController textController2 = TextEditingController();
String? errorshowingtext;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: Colors.blue[200]),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 150,
),
Text(
'Write down your task',
style: TextStyle(
fontSize: 25,
color: Colors.black,
fontWeight: FontWeight.normal),
),
SizedBox(
height: 25,
),
TextField(
autofocus: true,
decoration: InputDecoration(
hintText: 'What to Do', errorText: errorshowingtext),
style: TextStyle(fontSize: 22),
controller: textController,
),
TextField(
autofocus: true,
decoration: InputDecoration(
hintText: 'Deadline', errorText: errorshowingtext),
style: TextStyle(fontSize: 22),
controller: textController2,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
child: Text('OK'),
onPressed: () {
String? job = textController.text;
String? line = textController2.text;
Bucket newbucket = Bucket(job, line, false);
if (job.isNotEmpty && line.isNotEmpty) {
setState(() {
Navigator.pop(context, newbucket);
});
} else {
setState(() {
errorshowingtext = 'contents missing';
});
}
},
),
SizedBox(
width: 150,
),
ElevatedButton(
child: Text('Cancel'),
onPressed: () {
Navigator.pop(context);
},
),
],
)
],
),
),
);
}
}

You already have isDone to check the state. Your current method doesn't update the item check status, I prefer this way
class Bucket {
final String whattodo;
final String deadline;
final bool isDone;
Bucket({
required this.whattodo,
required this.deadline,
required this.isDone,
});
Bucket copyWith({
String? whattodo,
String? deadline,
bool? isDone,
}) {
return Bucket(
whattodo: whattodo ?? this.whattodo,
deadline: deadline ?? this.deadline,
isDone: isDone ?? this.isDone,
);
}
}
And the widget
class Homepage extends StatefulWidget {
const Homepage({Key? key}) : super(key: key);
#override
State<Homepage> createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('WhattoDo List')),
floatingActionButton: IconButton(
onPressed: () async {
Bucket newbucket = await Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => PopUp()));
setState(() {
bucketlist.add(newbucket);
});
},
icon: Icon(Icons.add)),
body: bucketlist.isEmpty
? Center(child: Text('List is empty'))
: ListView.builder(
itemCount: bucketlist.length,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: EdgeInsets.only(top: 5),
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.teal[200],
borderRadius: BorderRadius.circular(8)),
child: ListTile(
title: Text(
bucketlist[index].whattodo,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
decoration: bucketlist[index].isDone
? TextDecoration.lineThrough
: TextDecoration.none),
),
subtitle: Text(
bucketlist[index].deadline,
style: TextStyle(fontSize: 15),
),
trailing: IconButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Wanna remove?"),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Cancel"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
setState(() {
bucketlist.removeAt(index);
});
},
child: Text(
"OK",
style: TextStyle(color: Colors.pink),
),
),
],
);
},
);
},
icon: Icon(Icons.delete)),
leading: IconButton(
onPressed: () {
setState(() {
bucketlist[index] = bucketlist[index]
.copyWith(isDone: !bucketlist[index].isDone);
});
},
icon: Icon(
Icons.check,
color: bucketlist[index].isDone
? Colors.green
: Colors.red,
)),
));
},
),
);
}
}

you have to update the list todo value. not the Widget of Listile value.
change this
leading: IconButton(
onPressed: () {
setState(() {
// your code: donecheck = !donecheck;
bucketlist[index].isDone = !donecheck; // change to this
print(donecheck);
});
},

Related

How to save data locally using shared preferences

i want save data locally in device, when i will terminate my app and when i will reopen i want my previous data to be stored locally.so how i can save that using shared preferences in flutter
here my home page where i set value:
import 'package:flutter/material.dart';
import 'package:list_ex/product.dart';
import 'package:sizer/sizer.dart';
import 'package:list_ex/info.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'shared_pref.dart';
class Myhome extends StatefulWidget {
const Myhome({Key? key}) : super(key: key);
#override
State<Myhome> createState() => _MyhomeState();
}
class _MyhomeState extends State<Myhome> {
List <Data> productdata = [];
final myController = TextEditingController();
TextEditingController productController = TextEditingController();
TextEditingController prizeController = TextEditingController();
late SharedPreferences sharedPreferences;
#override
void initState() {
// TODO: implement initState
super.initState();
getprodata();
getpridata();
#override
void dispose() {
// Clean up the controller when the widget is disposed.
myController.dispose();
super.dispose();
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Products',
style: TextStyle(
fontSize: 30.0,
),
),
centerTitle: true,
backgroundColor: Colors.grey[800],
actions: [
IconButton(onPressed: () {
showDialog(context: context, builder: (context) =>
Dialog(
child: SizedBox(
height: 200,
width: 200,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
filled: true,
labelText: 'product',
icon: Icon(Icons.star),
),
controller: productController,
validator: (value){
if(value == null || value.isEmpty){
return 'Enter product name';
}
return null;
},
),
Divider(
height: 20.0,
color: Colors.grey[800],
),
///Text Field
TextFormField(
decoration: InputDecoration(
filled: true,
labelText: 'price',
icon: Icon(Icons.star),
),
keyboardType: TextInputType.number,
controller: prizeController,
),
ElevatedButton(onPressed: () {
if (productController.text.isEmpty && prizeController.text.isEmpty){
const AlertDialog(
title: Text('Enter Value'),
);
} else{
setState(() {
setprodata(productController.text);
setpridata(prizeController.text);
productdata.add(Data(productController.text, prizeController.text));
productController.text = "";
prizeController.text = "";
Navigator.of(context).pop();
});
}
}, child:
const Text('Submit')),
],
),
),
),
);
}, icon: Icon(Icons.add))
],
),
///app Drawer
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
decoration: BoxDecoration(
color: Colors.black45
),
accountName: Text('Raj'),
accountEmail: Text('abc123#gmail.com'),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.orange,
child:
Text('R', style:
TextStyle(fontSize: 40),),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.contact_mail),
title: Text('Contact Us'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
///Body of the app
body: ListView.builder(
itemCount: productdata.length,
itemBuilder: (BuildContext context, int index) {
return
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: ListTile(
tileColor: Colors.cyan,
leading: Icon(Icons.star),
trailing: IconButton(onPressed: () {
showDialog(context: context, builder: (context) =>
AlertDialog(
title: Text('Delte this?'),
content: Text('Are you sure?'),
actions: <Widget>[
TextButton(onPressed: () {
Navigator.pop(context);
}, child:
Text('Cancel')),
TextButton(onPressed: () {
setState(() {
productdata.remove(productdata[index]);
Navigator.pop(context);
});
}, child:
const Text('Delete', style:
TextStyle(
color: Colors.black87,
fontSize: 16,
),))
],
));
}, icon: Icon(Icons.delete)),
title: Text(productdata[index].product!,
style:
TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Info(value: productdata[index])));
},
)),
],
);
}),
);
}
}
i tried using shared preferences but i am not geting any value.
here my info page where i want to get values:
import 'package:flutter/material.dart';
import 'package:list_ex/home.dart';
import 'package:list_ex/product.dart';
import 'package:list_ex/shared_pref.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Info extends StatelessWidget {
final Data value;
var pro;
var pri;
#override
void initState() {
getprodata();
getpridata();
}
Info({Key? key, required this.value}) : super(key: key);
#override
Widget build(BuildContext context) {
var pridata;
var prodata;
return Scaffold(
appBar: AppBar(
title: Text('Product Info'),
centerTitle: true,
backgroundColor: Colors.grey[800],
),
body: Center(
child: Card(
color: Colors.cyan,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
// ignore: prefer_interpolation_to_compose_strings
title: Text('Product Name:' + value.product!, style:
TextStyle(
fontSize: 20,
),),
subtitle: Text('Price:' + value.prize!, style:
TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold
),),
),
],
),
),
)
);
}
}
first import shared_preferences library into your project.
make instance of preference.
final prefs = await SharedPreferences.getInstance();
now write or store data into preference
counter is for Key and 10 is value
await prefs.setInt('counter', 10);
what ever key you will give here it will store data into that key only through this key you can get you data.
you can store any type of data like for int type you have to use setInt for String type use setString() and so on..
now you can get this data through get
final int? counter = prefs.getInt('counter');
in getInt() just pass key that you want to get data.
and use only one instance in every screen of you project to write and get data.
for more information see https://pub.dev/packages/shared_preferences

Does anyone know what's going on with my Listview?

I needed to insert a TextField to search/filter records, but I don't know what's going on.
When I click on the "Cães" option of the BottomNavigationBar, on main.dart,
I only get a CircularProgressIndicator and the data does show up.
Have any of you experienced this problem?
Does anyone know why my Listview doesn't show up?
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:ssk_final/addeditpage.dart';
//import 'package:flutter_localizations/flutter_localizations.dart';
List<dynamic> list = [];
class CaesPage extends StatefulWidget {
// CaesPage({Key key}) : super(key: key);
#override
_CaesPageState createState() => _CaesPageState();
Widget build(BuildContext context) {
return Container(
child: Center(
child: Text("Cadastro de Cães"),
),
);
}
}
class _CaesPageState extends State<CaesPage> {
String searchString = "";
Future<List<Caes>> caes;
Future getData() async {
var url = 'http://.../api2.php?opcao=read';
var response = await http.get(Uri.parse(url));
return json.decode(response.body);
}
/*
Future _showMyDialog(id, nome) async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button
builder: (BuildContext context) {
return AlertDialog(
title: Text('Exclusão'),
content: SingleChildScrollView(
child: Column(
children: <Widget>[
Text('Confirma a exclusão de ' + nome + '?'),
],
),
),
actions: <Widget>[
TextButton(
child: Text('Confirma'),
onPressed: () {
setState(() {
var url = 'http://.../api.php?opt=delete';
http.post(Uri.parse(url), body: {
'id': id,
});
});
Navigator.pop(context, true);
},
),
TextButton(
child: Text('Cancelar'),
onPressed: () {
Navigator.pop(context);
},
),
],
);
},
);
}
*/
#override
void initState() {
super.initState();
caes = fetchCaes();
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Color.fromRGBO(1, 87, 155, 1),
focusColor: Colors.blue,
foregroundColor: Colors.white,
hoverColor: Colors.green,
splashColor: Colors.tealAccent,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddEditPage(),
),
);
debugPrint('Clicked FloatingActionButton Button');
},
),
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(),
//SizedBox(height: 10),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TextField(
onChanged: (value) {
setState(() {
searchString = value.toLowerCase();
});
},
decoration: const InputDecoration(
//contentPadding: EdgeInsets.symmetric(vertical: 10),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(25.0))),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(25.0)),
),
labelText: 'Pesquisa',
suffixIcon: Icon(Icons.search))),
),
SizedBox(height: 10),
Expanded(
child: FutureBuilder<List<Caes>>(
builder: (context, snapshot) {
if (snapshot.hasData) {
return Center(
child: ListView.separated(
padding: const EdgeInsets.all(8),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return snapshot.data[index].nome
.toLowerCase()
.contains(searchString)
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new InkWell(
onTap: () {
print(index);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddEditPage(
caes: snapshot.data,
index: index,
),
),
);
},
child: new Container(
child: Column(
children: [
Text(
(snapshot.data[index].nome),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold),
),
Text(
('${snapshot.data[index].microchip}'),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 13,
),
),
Text(
('${snapshot.data[index].pedigree}'),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 13,
),
),
Text(
(snapshot
.data[index].data_nascimento),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 13,
),
),
Text(
(snapshot.data[index].sexo),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 13,
),
),
Text(
(snapshot.data[index].castrado),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 13,
),
),
],
),
),
),
])
: Container();
},
separatorBuilder: (BuildContext context, int index) {
return snapshot.data[index].nome
.toLowerCase()
.contains(searchString)
? Divider()
: Container();
},
),
);
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
return Center(
child: CircularProgressIndicator(),
);
},
// future: list,
),
),
],
),
);
}
}
class Caes {
final int id;
final String nome;
final int microchip;
final int pedigree;
final String data_nascimento;
final String castrado;
final String sexo;
Caes({
this.id,
this.nome,
this.microchip,
this.pedigree,
this.data_nascimento,
this.castrado,
this.sexo,
});
factory Caes.fromJson(Map<String, dynamic> json) {
return Caes(
id: json['id'],
nome: json['nome'],
microchip: json['microchip'],
pedigree: json['pedigree'],
data_nascimento: json['data_nascimento'],
castrado: json['castrado'],
sexo: json['sexo'],
);
}
}
class Titulos {
Titulos({this.data, this.titulo, this.exposicao});
// non-nullable - assuming the score field is always present
final String data;
final String titulo;
final String exposicao;
factory Titulos.fromJson(Map<String, dynamic> json) {
final data = json['data'] as String;
final titulo = json['titulo'] as String;
final exposicao = json['exposicao'] as String;
return Titulos(data: data, titulo: titulo, exposicao: exposicao);
}
Map<String, dynamic> toJson() {
return {
'data': data,
'titulo': titulo,
'exposicao': exposicao,
};
}
}
Future<List<Caes>> fetchCaes() async {
final response = await http.get(Uri.parse('http://.../api.php?opt=read'));
if (response.statusCode == 200) {
var caesJson = jsonDecode(response.body) as List;
return caesJson.map((caes) => Caes.fromJson(caes)).toList();
} else {
throw Exception('Failed to load Caes');
}
}
Screen
I cant really provide an answer in your list view cause it needs more files to run for me. However I can provide you a nice way to search in a list for items and update it with a text field. You can copy and run the code in the main of a test project to see how it is working.
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final StreamController<List<String>> _exercisesStreamController =
StreamController<List<String>>();
late Stream<List<String>> _exercisesStream;
final List<String> _exercises = [
"Running",
"Swimming",
"Football",
"Basketball",
"Volleyball",
"Karate",
"Ski",
"Snowboard",
"Baseball",
"Running1",
"Swimming1",
"Football1",
"Basketball1",
"Volleyball1",
"Karate1",
"Ski1",
"Snowboard1",
"Baseball1",
"Running2",
"Swimming2",
"Football2",
"Basketball2",
"Volleyball2",
"Karate2",
"Ski2",
"Snowboard2",
"Baseball2",
"Running3",
"Swimming3",
"Football3",
"Basketball3",
"Volleyball3",
"Karate3",
"Ski3",
"Snowboard3",
"Baseball3",
];
#override
void initState() {
super.initState();
_exercisesStreamController.sink.add(_exercises);
_exercisesStream = _exercisesStreamController.stream.asBroadcastStream();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(),
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Column(
children: [
TextFormField(
maxLines: 1,
style: TextStyle(color: Colors.white),
onChanged: (String value) async {
List<String> temp = List.from(_exercises);
temp.removeWhere((element) =>
!element.toLowerCase().contains(value.toLowerCase()));
_exercisesStreamController.sink.add(temp);
},
decoration: InputDecoration(
prefixIcon: Icon(
Icons.search,
color: Colors.white,
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(15.0),
),
contentPadding: EdgeInsets.only(left: 15),
filled: true,
fillColor: Colors.blueGrey,
hintText: "search",
hintStyle: TextStyle(
color: Colors.white,
),
),
),
_listViewWidget()
],
),
),
);
}
Widget _listViewWidget() {
return Expanded(
child: StreamBuilder<List<String>>(
initialData: [],
stream: _exercisesStream,
builder: (context, snapshot) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.all(
Radius.circular(15),
),
),
padding: EdgeInsets.all(15),
margin: EdgeInsets.symmetric(vertical: 10),
child: Center(
child: Text(
snapshot.data![index],
style: TextStyle(color: Colors.white),
),
),
);
});
},
),
);
}
}
If you need further instructions i am happy to help.

Show drawer over bottom navigation bar in Flutter

I have a drawer in a appbar and need to show it over the bottom navigation bar but can't put both in the same view, I don't know exactly how to do this.
This is what it looks like now and this is what it needs to look like.
This is part of the code of the view where the appbar is
class ContactsPage extends StatefulWidget {
final String title;
final String token;
final String qr;
String code;
final String name;
ContactsPage({this.name, this.token, this.qr, this.code, Key key, this.title})
: super(key: key);
#override
_ContactsPageState createState() => _ContactsPageState();
}
class _ContactsPageState extends State<ContactsPage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
List<Contact> contactList;
bool showHorizontalBar = false;
bool ready = false;
#override
void initState() {
super.initState();
var userService = new UserService();
userService.getContacts(widget.token).then((value) => {
print(value),
if (value == '0')
{
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => LoginPage()))
}
else if (value == '3')
{
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => LoginPage()))
}
else
{
setState(() {
contactList = value;
ready = true;
})
},
print(contactList),
});
}
void showMessage(String message, [MaterialColor color = Colors.red]) {
_scaffoldKey.currentState..removeCurrentSnackBar();
_scaffoldKey.currentState.showSnackBar(
new SnackBar(backgroundColor: color, content: new Text(message)));
}
_navigateAndDisplaySelection(BuildContext context) async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Scanner(
qr: widget.qr,
token: widget.token,
)),
);
if (result != null) {
showMessage('$result', Colors.red);
}
}
Widget _addPerson() {
return FloatingActionButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: Icon(Icons.group_add),
backgroundColor: Color(0xff83bb37),
);
}
Widget buildMenuIcon() {
return IconButton(
icon: Icon(showHorizontalBar ? Icons.close : Icons.more_horiz),
onPressed: () {
setState(() {
showHorizontalBar = !showHorizontalBar;
});
},
);
}
Widget _simplePopup() => PopupMenuButton<int>(
itemBuilder: (context) => [
PopupMenuItem(
child: Row(
children: <Widget>[
IconButton(
icon: Icon(
Icons.delete,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
IconButton(
icon: Icon(
Icons.favorite,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
IconButton(
icon: Icon(
Icons.mail,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
IconButton(
icon: Icon(
Icons.calendar_today,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
IconButton(
icon: Icon(
Icons.call,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
],
),
)
],
icon: Icon(
Icons.more_horiz,
size: 20,
color: Color(0xff4d4c48),
),
);
Widget _card(String first_name, String last_name, String email) {
return Card(
clipBehavior: Clip.antiAlias,
child: Column(
children: [
SizedBox(
height: 5.0,
),
ListTile(
leading: ClipRRect(
borderRadius: BorderRadius.circular(13.0),
child: Image.asset(
'assets/images/mujer.jpg',
width: 60.0,
height: 70.0,
fit: BoxFit.cover,
),
),
title: Row(
children: [
Text(
first_name,
style: TextStyle(
fontWeight: FontWeight.bold, color: Color(0xff4d4c48)),
),
SizedBox(width: 5.0),
Text(
last_name,
style: TextStyle(
fontWeight: FontWeight.bold, color: Color(0xff4d4c48)),
)
],
),
subtitle: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
email,
style: TextStyle(color: Color(0xff4d4c48)),
),
SizedBox(
height: 5.0,
),
Text(
'Prowebglobal',
style: TextStyle(
color: Color(0xff4d4c48), fontWeight: FontWeight.w600),
),
],
),
),
trailing: _simplePopup(),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ContactDetails(token: widget.token, email: email)));
},
),
SizedBox(
height: 20.0,
),
],
),
);
}
Widget textContainer(String string, Color color) {
return new Container(
child: new Text(
string,
style: TextStyle(
color: color, fontWeight: FontWeight.normal, fontSize: 16.0),
textAlign: TextAlign.start,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
margin: EdgeInsets.only(bottom: 10.0),
);
}
Widget _titulo() {
return new Container(
alignment: Alignment.topLeft,
padding: EdgeInsets.only(left: 20.0),
child: new Text(
'Contactos',
style: TextStyle(
color: Color(0xff83bb37),
fontWeight: FontWeight.bold,
fontSize: 25.0),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
drawer: NavDrawer(
token: widget.token,
),
appBar: AppBar(
centerTitle: true,
backgroundColor: Color(0xfff0f0f0),
title: Image.asset(
'assets/images/logo-iso.png',
height: 50.0,
fit: BoxFit.contain,
alignment: Alignment.center,
),
iconTheme: new IconThemeData(color: Color(0xff707070)),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
},
),
]),
body: Column(children: [
SizedBox(
height: 20.0,
),
Expanded(
flex: 2,
child: _titulo(),
),
Expanded(
flex: 20,
child: Container(
child: ready
? ListView(
children: contactList
.map(
(Contact contact) => _card("${contact.first_name}",
"${contact.last_name}", "${contact.email}"),
)
.toList())
: Center(
child: Image.asset(
"assets/images/logo-gif.gif",
height: 125.0,
width: 125.0,
),
),
),
),
]),
floatingActionButton: _addPerson(),
);
}
}
And this is where de bottom navigation menu is
class HomePage extends StatefulWidget {
HomePage({
this.token,
this.code,
Key key,
}) : super(key: key);
final String token;
final String code;
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String currentPage = 'contacts';
changePage(String pageName) {
setState(() {
currentPage = pageName;
});
}
#override
Widget build(BuildContext context) {
final Map<String, Widget> pageView = <String, Widget>{
"contacts": ContactsPage(
code: widget.code,
token: widget.token,
),
"profile": ProfilePage(
token: widget.token,
),
};
return Scaffold(
body: pageView[currentPage],
bottomNavigationBar: new BottomNavigationDot(
paddingBottomCircle: 21,
color: Colors.black.withOpacity(0.5),
backgroundColor: Colors.white,
activeColor: Colors.black,
items: [
new BottomNavigationDotItem(
icon: Icons.home,
onTap: () {
changePage("contacts");
}),
new BottomNavigationDotItem(icon: Icons.brush, onTap: () {}),
new BottomNavigationDotItem(icon: Icons.notifications, onTap: () {}),
new BottomNavigationDotItem(icon: Icons.favorite, onTap: () {}),
new BottomNavigationDotItem(
icon: Icons.person,
onTap: () {
changePage("profile");
}),
],
milliseconds: 400,
),
);
}
}
Edit:
I have thought on putting de appbar in the same level as de bottom navigation bar but I need to put different options on the appbar depending on the view so I thought on using diferent appbars, that's why I wanted it on the same level as the view.

Flutter: Prevent Future Builder from firing

I am new to flutter and I'm trying to build a simple app. Whenever I update profile details from EditProfileScreen and try to return to ProfileScreen through LandingScreen, FutureBuilder keeps on firing and LogoScreen appears. How to avoid that?
I tried of using Navigator pop but my new data is not updated in that case. I can't Navigate to ProfileScreen directly as I don't want to loose my bottom navigation bar. Can anybody suggest me a right way to do this?
LandingScreen():
class LandingScreen extends StatefulWidget {
final int index;
LandingScreen({this.index});
#override
_LandingScreenState createState() => _LandingScreenState();
}
class _LandingScreenState extends State<LandingScreen> {
int _currentIndex = 0;
List<Futsal> list;
List<Search> listHistory;
List<Futsal> futsalList;
Future<dynamic> loadDataFuture;
final List<Widget> _children = [
HomePage(),
ExploreScreen(),
ProfileDetails(),
];
#override
void initState() {
onTappedBar(widget.index);
loadDataFuture = getFutureData();
super.initState();
}
void onTappedBar(int index) {
setState(() {
_currentIndex = index;
});
}
Future getFutureData() async {
listHistory = await fetchSearchs();
futsalList = await fetchFutsals();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: new FutureBuilder(
future: loadDataFuture,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('Please close the application and Try Again.');
case ConnectionState.waiting:
return LogoScreen();
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return Scaffold(
backgroundColor: Colors.white,
appBar: new AppBar(
automaticallyImplyLeading: false,
backgroundColor: kPrimaryLightColor,
title: Text(
'letsfutsal',
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
color: kPrimaryColor,
onPressed: () {
showSearch(
context: context,
delegate: SearchScreen(
futsalList: futsalList,
listHistory: listHistory));
},
),
],
),
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTappedBar,
currentIndex: _currentIndex,
selectedItemColor: kPrimaryColor,
unselectedItemColor: Colors.black38,
showSelectedLabels: false,
showUnselectedLabels: false,
items: [
BottomNavigationBarItem(
icon: new FaIcon(FontAwesomeIcons.home),
title: new Text(''),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.safari),
title: Text(''),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.solidUserCircle),
title: Text(''),
),
],
),
);
}
},
),
);
}
}
ProfileScreen():
class ProfileDetails extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CustomUserProvider()),
ChangeNotifierProvider(create: (context) => MyBookingsProvider()),
],
child: SafeArea(
child: Scaffold(
backgroundColor: kPrimaryLightColor,
appBar: new AppBar(
automaticallyImplyLeading: false,
elevation: 0,
title: Text(
'Profile',
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
actions: [
FlatButton.icon(
onPressed: () {},
icon: Icon(
FontAwesomeIcons.signOutAlt,
color: kPrimaryColor,
),
label: Text(
'Log Out',
style: TextStyle(
color: kPrimaryColor,
),
),
),
],
),
body: new Container(
padding: const EdgeInsets.all(15.0),
child: new Center(
child: new Column(
children: <Widget>[
UserDetails(),
MyBookingsList(),
],
),
),
),
),
),
);
}
}
class UserDetails extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final userProvider = Provider.of<CustomUserProvider>(context);
if (userProvider.user.length == 0) {
return Container();
} else {
return Column(
children: <Widget>[
new CircularImageContainer(
radius: 50,
imageUrl: "assets/images/profile.png",
),
SizedBox(height: size.height * 0.03),
Text(
userProvider.user[0].name != null ? userProvider.user[0].name : "",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
SizedBox(height: size.height * 0.01),
Text(
userProvider.user[0].address != null
? userProvider.user[0].address
: "",
),
FlatButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return EditProfileScreen(
user: userProvider.user[0],
);
},
),
);
},
icon: Icon(
Icons.edit,
color: kPrimaryColor,
),
label: Text(
'Edit Profile',
style: TextStyle(
color: kPrimaryColor,
),
),
),
],
);
}
}
}
class MyBookingsList extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final bookingsProvider = Provider.of<MyBookingsProvider>(context);
if (bookingsProvider.bookings.length == 0) {
return Container();
} else {
return Column(
children: <Widget>[
ScrollListContainer(
text: "My Bookings",
size: size,
),
ListView.builder(
shrinkWrap: true,
itemCount: bookingsProvider.bookings.length,
scrollDirection: Axis.vertical,
physics: BouncingScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Card(
child: Container(
width: 150,
child: ExpansionTile(
title: Text(
index.toString() +
'. ' +
bookingsProvider
.bookings[index].futsal.customUser.name !=
null
? bookingsProvider
.bookings[index].futsal.customUser.name
: "",
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
children: <Widget>[
ListTile(
title: Text(
bookingsProvider.bookings[index].status,
),
subtitle: Text(
'For ' + bookingsProvider.bookings[index].bookedFor,
),
dense: true,
),
],
),
),
);
},
),
],
);
}
}
}
EditProfileScreen():
class EditProfileScreen extends StatefulWidget {
final CustomUser user;
EditProfileScreen({this.user});
#override
_EditProfileScreenState createState() => new _EditProfileScreenState();
}
class _EditProfileScreenState extends State<EditProfileScreen> {
final scaffoldKey = new GlobalKey<ScaffoldState>();
final formKey = new GlobalKey<FormState>();
String _name;
String _address;
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
void _submit() {
final form = formKey.currentState;
if (form.validate()) {
form.save();
performUpdate();
}
}
void performUpdate() async {
Map data = {
'name': _name,
'address': _address,
};
var url =MY_URL;
var response = await http.post(url,
headers: {"Accept": "application/json"}, body: data);
print(response.body);
if (response.statusCode == 200) {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) => LandingScreen(index: 2,)));
}
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return new SafeArea(
child: Scaffold(
key: scaffoldKey,
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: true,
// automaticallyImplyLeading: false,
leading: BackButton(
color: kPrimaryColor,
),
elevation: 0,
backgroundColor: kPrimaryLightColor,
title: Text(
widget.user.name,
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
),
body: new Container(
height: size.height,
width: double.infinity,
padding: const EdgeInsets.all(30.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Edit Details",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: size.height * 0.03),
new Form(
key: formKey,
child: new Column(
children: <Widget>[
new TextFieldContainer(
child: new TextFormField(
controller:
TextEditingController(text: widget.user.name),
decoration: new InputDecoration(
labelText: "Name",
icon: Icon(
Icons.person,
color: kPrimaryColor,
),
border: InputBorder.none,
),
validator: (val) =>
val.isEmpty ? 'Please enter name' : null,
onSaved: (val) => _name = val,
),
),
new TextFieldContainer(
child: new TextFormField(
controller: TextEditingController(
text: widget.user.address != null
? widget.user.address
: ''),
decoration: new InputDecoration(
labelText: "Address",
icon: Icon(
Icons.email,
color: kPrimaryColor,
),
border: InputBorder.none,
),
validator: (val) =>
val.isEmpty ? 'Please enter your address' : null,
onSaved: (val) => _address = val,
),
),
RoundedButton(
text: "Update",
press: _submit,
),
],
),
),
],
),
),
),
),
);
}
}
As you are using Provider, you can do something like this.
#override
void initState() {
bloc = Provider.of<MyDealsBLOC>(context, listen: false);
if (!bloc.isLoaded) {
Future.delayed(
Duration.zero,
() => Provider.of<MyDealsBLOC>(context, listen: false).loadData(),
);
bloc.isLoaded = true;
print('IsLoaded: ${bloc.isLoaded}');
}
super.initState();
}
What I did is that I use a boolean isLoaded in my bloc to check whether data has been loaded once or not. I beleive you can do the same as well.
If you are trying to prevent a network image from keep downloading and loading you need to use cached_network_image to cache the image and it won't download again. Just put in the image download URL and the package will do the rest.

Search delegate , When I click on Search button it shows red screen with error child! =null

I create a search option by search delegate but When I click on search button it shows the red screen with this error "The following assertion was thrown building _SearchPage(dirty, dependencies: [_LocalizationsScope-[GlobalKey#69e74], _InheritedTheme], state: _SearchPageState#72bb6): 'package:flutter/src/widgets/basic.dart': Failed assertion: line 6938 pos 15: 'child != null': is not true.
import 'package:flutter/material.dart';
import 'package:grk_001/screen/main_screen.dart';
import 'widgets/entry_item.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:grk_001/screen/favourite_screen.dart';
import 'package:grk_001/Provider/Auth.dart';
import 'package:provider/provider.dart';
import 'package:grk_001/Provider/cart.dart';
import 'package:grk_001/widgets/badge.dart';
import 'package:grk_001/screen/cart_screen.dart';
import 'package:grk_001/widgets/drawer.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:grk_001/models/main_screen_categories_entry.dart';
class HomeScreen extends StatefulWidget {
static const String routename = 'homescreen';
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();
FirebaseUser Loggedinuser;
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
Future.delayed(Duration.zero).then((_) async {
await Provider.of<Auth>(context, listen: false).getcurrentuser();
});
super.didChangeDependencies();
}
#override
Widget build(BuildContext context) {
final devicesize = MediaQuery.of(context).size;
return SafeArea(
child: Scaffold(
key: _scaffoldkey,
appBar: AppBar(
leading: IconButton(
onPressed: () {
_scaffoldkey.currentState.openDrawer();
},
icon: Icon(
Icons.list,
color: Colors.white,
size: 35.0,
),
),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(50.0),
child: Container(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const SizedBox(
width: 10.0,
),
Expanded(
child: GestureDetector(
onTap: () {
_scaffoldkey.currentState.openEndDrawer();
},
child: Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.center,
height: 40.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5.0),
),
child: Text(
'Categories',
),
),
),
),
],
),
),
),
title: Text('HomeScreen'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch());
},
),
IconButton(
icon: Icon(
FontAwesomeIcons.heart,
size: 30.0,
),
tooltip: 'My Wish List',
onPressed: () {
Navigator.pushNamed(context, FavouriteScreen.routename);
},
),
IconButton(
icon: Icon(
Icons.notifications,
size: 30.0,
),
tooltip: 'My Notifications',
onPressed: () {},
),
Consumer<Cart>(
builder: (_, cartdata, ch) => Badge(
child: ch,
value: cartdata.itemcount.toString(),
),
child: IconButton(
onPressed: () {
Navigator.pushNamed(context, CartScreen.routename);
},
icon: Icon(
Icons.shopping_cart,
size: 40.0,
),
),
),
],
),
body: MainScreen(),
// body: CategoryScreen(),
endDrawer: Drawer(
child: Column(
children: <Widget>[
Container(
color: Color(0XFFFF4081),
height: devicesize.height * 0.10,
child: DrawerHeader(
margin: EdgeInsets.zero,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
Icons.apps,
color: Colors.white,
),
SizedBox(
width: 10.0,
),
Text(
'Categories',
style:
TextStyle(color: Colors.white, fontSize: 20.0),
),
],
),
)
// child: Text('Categories'),
),
),
Container(
height: devicesize.height * 0.85,
child: ListView.builder(
itemBuilder: (context, index) => EntryItem(data[index]),
itemCount: data.length,
),
)
],
),
),
drawer: Container(
width: devicesize.width * 0.65,
child: DrawerItem(devicesize, context),
),
),
);
}
}
class DataSearch extends SearchDelegate<String> {
final statelist = [
'Andaman and Nicobar Islands',
' Andhra Pradesh',
'Arunachal Pradesh',
'Assam',
'Bihar',
'Chandigarh ',
'Chhattisgarh',
'Dadra and Nagar Havel',
'Daman and Diu',
'Delhi',
'Goa',
'Gujrat',
'Haryana',
'Himachal Pradesh',
'Uttar Pradesh',
'Uttarakhand',
'West Bengal',
'Sikkim',
'Meghalya',
'Mizoram',
];
final recentlist = ['Modingar', 'Ghaziabad', 'Merrut', 'Hapur', 'Delhi'];
#override
List<Widget> buildActions(BuildContext context) {
// action for app bar
return [
IconButton(
onPressed: () {
query = "";
},
icon: Icon(Icons.clear),
)
];
}
#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) {
// TODO: implement buildResults
return Container(
height: 150.0,
child: Card(
color: Colors.red,
shape: StadiumBorder(),
child: Text(query),
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
final suggestionList = query.isEmpty
? recentlist
: statelist.where((element) => element.startsWith(query)).toList();
ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context);
},
title: RichText(
text: TextSpan(
text: suggestionList[index].substring(0, query.length),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: suggestionList[index].substring(query.length),
style: TextStyle(color: Colors.grey))
]),
)),
itemCount: suggestionList.length,
);
}
}
You can copy paste run full code below
You need return keyword in buildSuggestions
You can return ListView.builder
code snippet
#override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
final suggestionList = query.isEmpty
? recentlist
: statelist.where((element) => element.startsWith(query)).toList();
return ListView.builder(
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title), actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch());
},
),
]),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class DataSearch extends SearchDelegate<String> {
final statelist = [
'Andaman and Nicobar Islands',
' Andhra Pradesh',
'Arunachal Pradesh',
'Assam',
'Bihar',
'Chandigarh ',
'Chhattisgarh',
'Dadra and Nagar Havel',
'Daman and Diu',
'Delhi',
'Goa',
'Gujrat',
'Haryana',
'Himachal Pradesh',
'Uttar Pradesh',
'Uttarakhand',
'West Bengal',
'Sikkim',
'Meghalya',
'Mizoram',
];
final recentlist = ['Modingar', 'Ghaziabad', 'Merrut', 'Hapur', 'Delhi'];
#override
List<Widget> buildActions(BuildContext context) {
// action for app bar
return [
IconButton(
onPressed: () {
query = "";
},
icon: Icon(Icons.clear),
)
];
}
#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) {
// TODO: implement buildResults
return Container(
height: 150.0,
child: Card(
color: Colors.red,
shape: StadiumBorder(),
child: Text(query),
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
final suggestionList = query.isEmpty
? recentlist
: statelist.where((element) => element.startsWith(query)).toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context);
},
title: RichText(
text: TextSpan(
text: suggestionList[index].substring(0, query.length),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: suggestionList[index].substring(query.length),
style: TextStyle(color: Colors.grey))
]),
)),
itemCount: suggestionList.length,
);
}
}