Flutter - How to search in List and display in ListView? - flutter

I'm coding a search system for the Flutter application I've developed. I'm having a problem with the back-end. First I pull the data from Firebase Firestore. Then I convert it to Model structure.
The code of the search system:
StreamBuilder(
stream: db.collection("DebrisPeoples").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
final List<DebrisPeopleModel> data = snapshot.data!.docs
.map((e) => DebrisPeopleModel.fromDocument(e))
.toList(); // To Model code
return Column(
children: [
const SizedBox(height: 10),
SizedBox(
width: MediaQuery.of(context).size.width * 0.95,
child: TextFormField(
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
contentPadding: const EdgeInsets.only(),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
),
),
onChanged: (value) {
final find = data.where(
(element) => data.contains(element.nameSurname));
print(find); // PROBLEM - NOT WORKING
},
),
),
SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.8,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Icon(
data[index].personSize == 1
? Icons.person
: Icons.people,
),
title: Text(data[index].nameSurname.toString()),
subtitle: Text(
"${data[index].city} / ${data[index].district}",
),
trailing: IconButton(
icon: const Icon(Icons.info),
onPressed: () {
Get.to(const UnderRublePeopleDetailPage(),
arguments: data[index]);
print(data[index].nameSurname);
},
),
),
);
},
),
),
],
);
}
},
),
I'm having the problem in the query part. My goal is, for example, if there is a record in the form of ABC, I want it to appear in the results even if the user searches for A or AB.
Then I want the results to be displayed in the list. I will be grateful for your help :)
To change search results:
final find = data.where((element) => element
.nameSurname!
.toLowerCase()
.contains(value.toLowerCase()));
print(find);
setState(() {
data = find.toList();
print(data);
});
I tried to make such a search system. However, the results in the ListView do not change as I enter the TextFormField.

Your onChanged code should be as following.
onChanged: (value) {
final find = data.where(
(element) => element.nameSurname.toLowerCase().contains(value.toLowerCase()));
print(find);
}
Make sure you are managing the state to reflect the changes on UI.
Edited
final controller = TextEditingController();//Keep this as a field
StreamBuilder(
stream: db.collection("DebrisPeoples").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
final searchText = controller.text.trim().toLowerCase();
final List<DebrisPeopleModel> data = snapshot.data!.docs
.map((e) => DebrisPeopleModel.fromDocument(e))
.where((e) => searchText.isEmpty || e.nameSurname!
.toLowerCase().contains(searchText))
.toList(); // To Model code
return Column(
children: [
const SizedBox(height: 10),
SizedBox(
width: MediaQuery
.of(context)
.size
.width * 0.95,
child: TextFormField(
controller: controller,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
contentPadding: const EdgeInsets.only(),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
),
),
onChanged: (value) {
setState((){ });
},
),
),
SizedBox(
width: double.infinity,
height: MediaQuery
.of(context)
.size
.height * 0.8,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Icon(
data[index].personSize == 1
? Icons.person
: Icons.people,
),
title: Text(data[index].nameSurname.toString()),
subtitle: Text(
"${data[index].city} / ${data[index].district}",
),
trailing: IconButton(
icon: const Icon(Icons.info),
onPressed: () {
Get.to(const UnderRublePeopleDetailPage(),
arguments: data[index]);
print(data[index].nameSurname);
},
),
),
);
},
),
),
],
);
}
},
)

Related

passing data immediately without using setstate

Is there a way to pass data when from alert dialogue box to the same screen immediately without using setstate?
Widget setupShadeColorContainer(
List<ShadeColorDatabase> allShadeData, BuildContext context) {
return SizedBox(
height: 300.0, // Change as per your requirement
width: 300.0, // Change as per your requirement
child: GridView.builder(
shrinkWrap: true,
itemCount: allShadeData.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, crossAxisSpacing: 10, mainAxisSpacing: 10),
itemBuilder: (ctx, i) {
return GestureDetector(
onTap: () {
rPassedChooseColor = allShadeData[i].rValue;
gPassedChooseColor = allShadeData[i].gValue;
bPassedChooseColor = allShadeData[i].bValue;
setState(() {
Navigator.pop(context, [
rPassedChooseColor,
gPassedChooseColor,
bPassedChooseColor
]);
});
},
child: Container(
child: Stack(
children: [
Container(
color: Color.fromRGBO(
allShadeData[i].rValue!.toInt(),
allShadeData[i].gValue!.toInt(),
allShadeData[i].bValue!.toInt(),
1),
),
Padding(
padding: const EdgeInsets.only(top: 45, left: 5),
child: Text("${allShadeData[i].colorCode}"),
)
],
),
),
);
}),
);
}
showAllColors(
List<ShadeColorDatabase> shadeData, BuildContext context) async {
final size = MediaQuery.of(context).size;
final GlobalKey<FormState> _form = GlobalKey<FormState>();
TextEditingController searchController = TextEditingController();
showDialog(
barrierDismissible: true,
context: context,
builder: (ctx) {
return WillPopScope(
onWillPop: () async => false,
child: AlertDialog(
title: Center(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Fashion's Color",
style: TextStyle(
color: ChooseColor(0).appBarColor1, fontSize: 14),
),
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(Icons.clear))
],
),
Form(
key: _form,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide: BorderSide.none,
),
contentPadding: EdgeInsets.symmetric(
vertical: size.height * 0.001,
horizontal: size.width * 0.030),
errorBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.red, width: 1),
borderRadius: BorderRadius.circular(5)),
// labelText: 'Phone Number',
fillColor: const Color(0xffF6F9FA),
filled: true,
hintText: 'Search Color',
prefixIcon: const Icon(Icons.search),
hintStyle: TextStyle(
fontSize: size.height * 0.012 +
size.width * 0.012,
color: Colors.black26),
),
controller: searchController,
),
SizedBox(height: size.height * 0.035),
],
)),
],
),
),
content: setupShadeColorContainer(shadeData, context),
),
);
});
This is my dialogue box this dilogue box open over a screen and i want to pass data from this dilogue box to the same page immediately without using setstate is there any way i can achieve that?. Thanks
showDialog() can return future, and you can return data(myData) on closing dialog using
Navigator.of(context).pop(myData);
showAllColors() async {
final data = await showDialog(context: context, builder: (c){
// on closing dialog
Navigator.of(context).pop(passData);
return data;
}
When you use showAllColors try putting await on async method and also make sure to handle null data.

Can't make a single select with a Switch or a RadioListTile flutter

i'm trying to make an Extra Food Items List it's for a Delivery App. The module of restaurants requiere these , but my issue is when I use a RadioListTile or a SwitchListTile it is possible to select more than one option, all the data is from an API where the Admin of some restaurant put the products. What i try to do is to make a ListView. separated for the Extra Groups (eg."Presa") and my Extras are the products or toppings that some product can have
Widget build(BuildContext context) {
return SwitchListTile.adaptive(
activeColor: Theme.of(context).accentColor,
// checkColor: Theme.of(context).primaryColor,
value: widget.extra.checked,
onChanged:(value) {
setState(() {
//widget.extra.checked = value;
widget.extra.checked = !widget.extra.checked;
widget.onChanged();
Future.delayed(Duration(milliseconds: 200),(){
Navigator.pop(context);
});
widget.onSelectedExtra;
});
},
title: Text(
widget.extra?.name,
style: Theme.of(context).textTheme.headline3.merge(TextStyle(
color: Theme.of(context).shadowColor,
fontSize: 16
)),
textAlign: TextAlign.start,
),
subtitle: widget.extra.price == 'null' || widget.extra.price == null || widget.extra.price == '0' || widget.extra.price == 0
? Helper.getPrice(0, context, style: Theme.of(context).textTheme.headline4.merge(TextStyle(
color: Theme.of(context).accentColor
)),)
:Helper.getPrice(widget.extra.price, context, style: Theme.of(context).textTheme.headline4.merge(TextStyle(
color: Theme.of(context).accentColor
)),),
);
}
}
In this section i'm calling just one Extra Food so i can return inside a list in the other section
if (_con.product.extraGroups == null)
CircularLoadingWidget(height: 100)
else
ListView.separated(
padding: EdgeInsets.all(0),
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
controller: ScrollController(initialScrollOffset: 600),
itemBuilder: (context, extraGroupIndex) {
var extraGroup = _con.product.extraGroups.elementAt(extraGroupIndex);
return Wrap(
children: <Widget>[
ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.add_circle_outline,
color: Theme.of(context).accentColor
),
title: Text(
extraGroup?.name ?? '',
style: Theme.of(context).textTheme.subtitle1.merge(TextStyle(
color: Theme.of(context).accentColor,
fontWeight: FontWeight.w600,
fontSize: 16
)),
),
),
Container(
decoration: BoxDecoration(
),
child: ListTile(
title:Text('Seleccione su ${extraGroup.name}',
style: Theme.of(context).textTheme.caption.merge(TextStyle(
color: Theme.of(context).shadowColor,
//fontWeight: FontWeight.w600,
fontSize: 13
)),
),
trailing: FlatButton(
color: Theme.of(context).focusColor.withOpacity(0.4),
shape:RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)
),
onPressed:(){
showModalBottomSheet(
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(30),topRight: Radius.circular(30))
),
context: context,
builder: (context){
return Wrap(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
child: ListView.separated(
padding: EdgeInsets.all(0),
itemBuilder: (context, extraIndex) {
return ExtraItemWidget(
extra: _con.product.extras.where((extra) => extra.extraGroupId == extraGroup.id && extra.multiple_selection == true ).elementAt(extraIndex),
onChanged: _con.calculateTotal,
);
},
separatorBuilder: (context, index) {
return SizedBox(height: 0);
},
itemCount: _con.product.extras.where((extra) => extra.extraGroupId == extraGroup.id && extra.multiple_selection == true).length,
primary: false,
shrinkWrap: true,
),
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: ListView.builder(
itemBuilder: (context, extraIndex) {
return ExtraSingleItemWidget(
extra: _con.product.extras.where((extra) => extra.extraGroupId == extraGroup.id && extra.multiple_selection == false).elementAt(extraIndex),
onChanged: _con.calculateTotal,
onSelectedExtra: _con.SelectedExtra,
);
},
itemCount: _con.product.extras.where((extra) => extra.extraGroupId == extraGroup.id && extra.multiple_selection == false).length,
primary: false,
shrinkWrap: true,
),
),
],
);
});
},
child: Wrap(
children: [
Text(
'Seleccionar',
style: Theme.of(context).textTheme.button.merge(TextStyle(
color: Theme.of(context).shadowColor
)),
),
],
),
),
),
),
],
);
},
separatorBuilder: (context, index) {
return Divider(thickness:1.5,height: 20);
},
itemCount: _con.product.extraGroups.length,
primary: false,
shrinkWrap: true,
),
I'm calling like ExtraSingleItemWidget, once the user select an extra it add to the base price but if the user want to select another extra from the modal bottom sheet it select more than one and I just need one at a time.enter image description here
enter image description here

Why my data from sqlite DB update only when I restart Flutter app?

I have a problem with my Data from sqlite Database. I have to restart app to see results of every changes (adding note, update note or deleting note). I don't know how to fix it. Can someone tell me what is wrong or what I forgot in my code.
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: _titleController,
decoration: InputDecoration(
hintText: "Note title",
),
),
TextField(
controller: _textController,
decoration: InputDecoration(
hintText: 'Note text',
),
),
_NoteButton((widget.noteMode == NoteMode.Adding ? 'Save note' : 'Edit note'),
widget.noteMode == NoteMode.Adding ? Colors.lightBlue : Colors.yellow, () {
if (widget.noteMode == NoteMode.Adding) {
final title = _titleController.text;
final text = _textController.text;
NoteProvider.insertNote({
'title': title,
'text': text
});
}
else if (widget.noteMode == NoteMode.Editing){
NoteProvider.updateNote({
'id': widget.note?['id'],
'title': _titleController.text,
'text': _textController.text,
});
}
Navigator.pop(context);
}
),
widget.noteMode == NoteMode.Editing ?
Padding(
padding: const EdgeInsets.only(left: 8),
child: _NoteButton('DELETE', Colors.red, () async {
await NoteProvider.deleteNote(widget.note?['id']);
Navigator.pop(context);
}),
) : Container()
],
),
),
It looks like Nagigator.pop() didn't update my notes list.
Have I forgotten something?
Notes list
future: NoteProvider.getNoteList(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
final notes = snapshot.data;
return ListView.builder(
itemBuilder: (context, index) {
return GestureDetector(
/*child: Container(
padding: EdgeInsets.all(20),*/
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) =>
NotePage(NoteMode.Editing, notes[index]))
);
},
child: Card(
child: Padding(
padding: const EdgeInsets.only(
top: 30.0, bottom: 30.0, left: 13, right: 22),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_NoteTitle(notes[index]['title']),
Container(height: 3,),
_NoteText(notes[index]['text']),
],
),
),
),
);
},
itemCount: notes.length,
);
}
return Center(child: CircularProgressIndicator());
},
),
You can use state management package like Mobx for it, or you can call again your function to get data from your database, or you can use FutureBuilder, and whenever you edit, delete, or add new data, call setState to update your list.

Flutter General dialog box - set state not working

I have an issue with my General Dialog Box. I would like to display a star. Then I would like to change it state when the star is taped and replace the icon by a yellow Star.
But is does not work. The Dialog Box is not refreshed so the icon is not changing. Please, can you look at the source code below and point me into the right direction please?
Many thanks.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:date_time_picker/date_time_picker.dart';
import 'package:gtd_official_sharped_focused/snackbar.dart';
String _isImportantInboxTask ;
String _isUrgentInboxTask ;
String inboxTaskDisplayed;
String isImportant = "false" ;
String isUrgent = "false" ;
String myProjectName ;
var taskSelectedID;
//---------------
//String _initialValue;
//_-----------------
var documentID;
var textController = TextEditingController();
var popUpTextController = TextEditingController();
class Inbox extends StatefulWidget {
Inbox({Key key}) : super(key: key);
#override
_InboxState createState() => _InboxState();
}
class _InboxState extends State<Inbox> {
GlobalKey<FormState> _captureFormKey = GlobalKey<FormState>();
bool isOn = true;
#override
Widget build(BuildContext context) {
void showAddNote() {
TextEditingController _noteField = new TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return CustomAlertDialog(
content: Container(
width: MediaQuery.of(context).size.width / 1.3,
height: MediaQuery.of(context).size.height / 4,
child: Column(
children: [
TextField(
controller: _noteField,
maxLines: 4,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1.0),
),
),
),
SizedBox(height: 10),
Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(25.0),
color: Colors.white,
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width / 1.5,
onPressed: () {
Navigator.of(context).pop();
CollectionReference users = FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('allTasks');
users
.add({'task_Name': _noteField.text,'task_Status': 'Inbox' })
.then((value) => print("User Document Added"))
.catchError((error) =>
print("Failed to add user: $error"));
},
padding: EdgeInsets.fromLTRB(10.0, 15.0, 10.0, 15.0),
child: Text(
'Add Note',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
);
});
}
return Scaffold(
appBar: new AppBar(
title: new Text('Inbox Page'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.add_circle_outline,
color: Colors.white,
),
onPressed: () {
showAddNote();
// do something
},
),
],
),
drawer: MyMenu(),
backgroundColor: Colors.white,
body: Column(
//mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: MediaQuery.of(context).size.height / 1.4,
width: MediaQuery.of(context).size.width,
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('allTasks')
.where('task_Status', isEqualTo: 'Inbox')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView(
children: snapshot.data.docs.map((document) {
return Wrap(
children: [Card(
child: SwipeActionCell(
key: ObjectKey(document.data()['task_Name']),
actions: <SwipeAction>[
SwipeAction(
title: "delete",
onTap: (CompletionHandler handler) {
CollectionReference users = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance.currentUser.uid)
.collection('allTasks');
users
.doc(document.id)
.delete()
.then((value) => print("Note Deleted"))
.catchError((error) => print(
"Failed to delete Task: $error"));
},
color: Colors.red),
],
child: Padding(
padding: const EdgeInsets.all(0.0),
child: ListTile(
leading: ConstrainedBox(
constraints: BoxConstraints(
minWidth: leadingIconMinSize,
minHeight: leadingIconMinSize,
maxWidth: leadingIconMaxSize,
maxHeight: leadingIconMaxSize,
),
child: Image.asset('assets/icons/inbox.png'),
),
title: GestureDetector(
child: Text(
//'task_Name' correspond au nom du champ dans la table
document.data()['task_Name'],
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
// Pour editer task
onDoubleTap: (){
taskSelectedID = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance.currentUser.uid)
.collection('allTasks')
.doc(document.id);
//Dialog
return showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context)
.modalBarrierDismissLabel,
barrierColor: Colors.black45,
transitionDuration: const Duration(milliseconds: 20),
pageBuilder: (BuildContext buildContext,
Animation animation,
Animation secondaryAnimation) {
return Scaffold(
appBar: AppBar(
title: Text ('Edit Task'),
leading: InkWell(
child: Icon(Icons.close),
onTap:(){Navigator.of(context).pop();}
),
actions: [Padding(
padding: const EdgeInsets.fromLTRB(0, 0,16.0,0),
child: InkWell(
child: Icon(Icons.save),
onTap: () {
final loFormInbox = _captureFormKey
.currentState;
if (loFormInbox.validate()) {
loFormInbox.save();
CollectionReference users = FirebaseFirestore
.instance
.collection(
'Users')
.doc(FirebaseAuth
.instance
.currentUser.uid)
.collection(
'allTasks');
users
.add({
'task_Name': _valueTaskNameSaved,
})
.then((value) =>
print(
"Task Created"))
.catchError((
error) =>
print(
"Failed to add task: $error"));
showSimpleFlushbar(
context,
'Task Saved',
_valueTaskNameSaved,
Icons
.mode_comment);
loFormInbox.reset();
isImportant = 'false';
isUrgent = 'false';
}
}
),
)],
),
body: Center(
child: Container(
width: MediaQuery.of(context).size.width - 10,
height: MediaQuery.of(context).size.height - 80,
padding: EdgeInsets.all(20),
color: Colors.white,
child: Column(
children: [
Theme(
data: ThemeData(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
)
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 15.0, 1.0),
child: TextFormField(
initialValue: document.data()['task_Name'],
decoration: InputDecoration(hintText: "Task Name"),
maxLength: 70,
maxLines: 2,
onChanged: (valProjectName) => setState(() => _valueTaskNameChanged = valProjectName),
validator: (valProjectName) {
setState(() => _valueTaskNameToValidate = valProjectName);
return valProjectName.isEmpty? "Task name cannot be empty" : null;
},
onSaved: (valProjectName) => setState(() => _valueTaskNameSaved = valProjectName),
),
)),
//Test Energy et Time / Important /urgent
Material(
child:
Container(
// color: Colors.red,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
//Important
FlatButton(
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isImportant =="true" ? Icon(Icons.star,color: Colors.orange,) :
Icon(Icons.star_border, color: Colors.grey,),
// Icon(Icons.battery_charging_full),
Text('Important'),
],
)
),
onTap: () {
setState(() {
if (isImportant=='true'){
isImportant = 'false';}
else
{isImportant= 'true';
}
});
},
),
),
RaisedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"Close",
style: TextStyle(color: Colors.white),
),
color: const Color(0xFF1BC0C5),
)
//++++++++++++++++
],
),
),
),
);
});
},
),
),
),
),
),
),
]
);
}).toList(),
);
}),
),
],
),
bottomNavigationBar: MyBottomAppBar(), //PersistentBottomNavBar(),
);
}
}
#override
Widget build(BuildContext context){
return _widget();
}
}
Thanks to your solution, I am able to do what I was willing to do. But now, I have an other issue. In the version 1 of my code, I am using this code
Theme(
data: ThemeData(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
)
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 15.0, 1.0),
child: TextFormField(
initialValue: document.data()['task_Name'],
decoration: InputDecoration(hintText: "Task Name"),
maxLength: 70,
maxLines: 2,
onChanged: (valProjectName) => setState(() => _valueTaskNameChanged = valProjectName),
validator: (valProjectName) {
setState(() => _valueTaskNameToValidate = valProjectName);
return valProjectName.isEmpty? "Task name cannot be empty" : null;
},
onSaved: (valProjectName) => setState(() => _valueTaskNameSaved = valProjectName),
),
)),
This part was working well. But after the modifications, I am getting an error. The error is about document.
Undefined name 'document'. Try correcting the name to one that is defined, or defining the name.
Please, can you help me with this so I can finalize this page. Thank you
So you want to change the color of icon on clicking it inside dialogBox,
but unfortunately you are using stateless widget Scaffold in return of showGeneralDialog builder so one thing that can possibly help is to make a separate StateFull Widget RatingDialogBox and use that in the builder.
Also instead of InkWell you can use IconButton
I will suggest you to use this package it is great
flutter_rating_bar
also feel free to comment is this doesn't satisfy your need

Flutter close a dialog and reload page with filtered list of the condition selected

import 'package:flutter_event_app/constant/color.dart';
import 'package:flutter_event_app/network/models/categories.dart';
import 'package:flutter_event_app/network/models/event_model.dart';
import 'package:flutter_event_app/network/models/time.dart';
import 'package:flutter_event_app/network/services/event_api.dart';
import 'package:flutter_event_app/pages/event_detail_page.dart';
import 'package:flutter_event_app/pages/search/home_search.dart';
import 'package:flutter_event_app/widgets/event_card.dart';
import 'package:flutter_event_app/widgets/no_events.dart';
import 'package:flutter_event_app/widgets/onload.dart';
class SelectedCategory extends StatefulWidget {
// SelectedCategory(Categories categories);
final Categories categories;
final Time time;
SelectedCategory(this.categories, [this.time]);
#override
_SelectedCategoryState createState() => _SelectedCategoryState();
}
class _SelectedCategoryState extends State<SelectedCategory> {
Categories categories;
Time timing;
String timeselect;
// Event event;
void viewEventDetail(Events event) {
Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 300),
pageBuilder: (BuildContext context, animation, __) {
return FadeTransition(
opacity: animation,
child: EventDetailPage(event),
);
},
),
);
}
bool isLoading = false;
List<Events> upcomingEvents;
List categorizedupcomingEvents = [];
List categorizedPaidupcomingEvents = [];
List categorizedFreeupcomingEvents = [];
#override
void initState() {
_fetchData();
categories = widget.categories;
timing = widget.time;
// print(timing.id);
super.initState();
}
Future _fetchData() async {
setState(() => isLoading = true);
upcomingEvents = await getEventss();
categorizedupcomingEvents = upcomingEvents
.where((category) => category.category == categories.id)
.toList();
categorizedPaidupcomingEvents = categorizedupcomingEvents
.where((paid) => paid.is_paid == true)
.toList();
categorizedFreeupcomingEvents = categorizedupcomingEvents
.where((free) => free.is_paid == false)
.toList();
setState(() => isLoading = false);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(
MediaQuery.of(context).size.height / 9.5,
),
child: AppBar(
title: Text(categories.categoryName),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.sort,
),
onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
showFilterByTimeDialog(context);
// )
// );
}),
IconButton(
icon: Icon(
Icons.more_vert,
),
onPressed: () {})
],
bottom: TabBar(
tabs: [
Text('All'),
Text('Paid'),
Text('Free'),
],
),
),
),
body: TabBarView(
children: <Widget>[
// All
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount: categorizedupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
// Paid
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedPaidupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount:
categorizedPaidupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedPaidupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
// Free
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedFreeupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount:
categorizedFreeupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedFreeupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
],
),
));
}
void showFilterByTimeDialog(BuildContext context) {
Dialog fancyDialog = Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: SingleChildScrollView(
child: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.5,
// alignment: Alignment.bottomCenter,
decoration: BoxDecoration(
// color: Colors.greenAccent,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
bottomLeft: Radius.circular(12),
bottomRight: Radius.circular(12),
),
),
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.05,
child: Text(
"Time",
style: TextStyle(
color: Colors.deepPurple,
fontSize: 20,
fontWeight: FontWeight.w600),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
// color: Colors.red,
width: double.infinity,
child: ListView.builder(
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
itemCount: times.length,
itemBuilder: (context, int index) {
Time time = times[index];
return RaisedButton(
onPressed: () {
debugPrint('I am Awesome');
},
textColor: Colors.red,
// color: Colors.blueAccent,
disabledColor: Colors.grey,
disabledTextColor: Colors.white,
highlightColor: Colors.orangeAccent,
child: Text(time.name),
);
}),
),
),
),
],
),
),
),
);
showDialog(
context: context, builder: (BuildContext context) => fancyDialog);
}
}
Within the same page I have a dialog box as shown below
On the method showFilterByTimeDialog where I select an item and have to go back to the same page below the dialogue .Am still learning flutter and my issue is I need help when I select an item from the dialogue box,i refresh the same page and display a new filtered lst from the current list displayed on that page with a condition of the item selected from the dialogue box.