assigning icon value based on data from flutter sqflite - flutter

I'm trying to load the favorite button on my card based on the data from database inside the future builder. while using the following code inside ListView.Builder, is sets the value to true and button click does not change it. I think it is because of FutureBuilder.
txtData.zFavourite == null
? isFavourite[index] = false
: isFavourite[index] = true;
it also requires to initialize the value for isFavourite and if it is assigned outside the widget, I do not get the data from database as it directly loads into the future builder.
how do we assign the value for isFavourite based on the data from the database and change the favourite icon based on the button click?
I also checked this link to handle button clicks for the individual list.
late List<bool> isFavourite = [false, false];
Widget _displayZhesa() {
return FutureBuilder<List<Zhebsa>>(
future: _getZhebsa(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
final txtData = snapshot.data![index];
txtData.zFavourite == null
? isFavourite[index] = false
: isFavourite[index] = true;
return Card(
elevation: 10,
color: Colors.white70,
shadowColor: Colors.amber[500],
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.all(5.0),
width: double.infinity,
decoration: BoxDecoration(
color: Colors.orange[400],
border: Border.all(
color: Colors.amber.shade100,
width: 2,
),
),
child: Center(
child: Text(
sQuery,
style: const TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w500),
),
),
),
Row(
children: <Widget>[
Center(
child: IconButton(
onPressed: () {
setState(() {
isFavourite[index] = !isFavourite[index];
});
},
/* () =>
_setFaviurite(txtData.zFavourite, index), */
icon: Icon(
isFavourite[index]
? Icons.favorite_sharp
: Icons.favorite_border_sharp,
size: 30.0,
color: Colors.redAccent,
),
),
),
Expanded(
child: ListTile(
title: const Text('ཞེ་ས།'),
subtitle: Text(txtData.zWord), //ཞེ་སའི་ཚིག
),
),
Container(
padding: const EdgeInsets.only(right: 20),
child: IconButton(
onPressed: () {
isPlayingPronunciation
? stopPronunciation()
: _playPronunciation(
'${txtData.zPronunciation}');
setState(() {
isPlayingPronunciation =
!isPlayingPronunciation;
});
},
icon: Icon(
isPlayingPronunciation
? Icons.stop_circle_outlined
: Icons.volume_up,
size: 50.0,
color: Colors.blue,
),
),
),
],
),
Container(
padding: const EdgeInsets.only(left: 30.0),
child: ListTile(
title: const Text('དཔེར་བརྗོད།'),
subtitle: SelectableText('${txtData.zPhrase}'),
),
),
],
),
);
},
);
} else {
return const Text('No Data');
}
});
}

Related

How to show loading indicator on only one list item in Flutter?

I have a list of items with buttons. By clicking on one element on the button, I get a CircularProgressIndicator. I ran into a problem that when I click on one card per button, I get a loading indicator on all cards. How can I make the loading indicator appear on only one card that I click on?
bool isApprovedLoading = false;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: MediaQuery.removePadding(
context: context,
removeTop: true,
child: Padding(
padding: const EdgeInsets.only(top: 10, bottom: 18),
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: list.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 7.0, sigmaY: 7.0),
child: Container(
height: 152,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color:
constants.Colors.greyXDark.withOpacity(0.8),
),
child: Row(
children: [
Expanded(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
isApprovedLoading
? const CircularProgressIndicator(
color: constants
.Colors.purpleMain)
: OrderButton(
text: 'Approved',
svgIcon:
SvgPicture.asset(
constants.Assets
.enable,
color: constants
.Colors
.purpleMain),
textStyle: const TextStyle(
fontFamily: constants
.FontFamily
.AvenirLtStd,
fontSize: 12,
fontWeight:
FontWeight.w800,
color: constants
.Colors
.purpleMain),
borderColor: constants
.Colors.purpleMain,
buttonColor: constants
.Colors.greyXDark
.withOpacity(0.5),
onTap: () {
setState(() {
isApprovedLoading =
true;
});
_confirmOrder(
context,
list[index].id,
poyntBookingsCubit,
user,
);
},
),
],
),
),
],
),
),
),
),
],
),
),
),
),
);
},
)
),
),
);
you need define new variable like:
int selectedItem = -1;
and change your asdasd to this:
onTap: () {
setState(() {
isApprovedLoading = true;
selectedItem = index;
});
_confirmOrder(
context,
list[index].id,
poyntBookingsCubit,
user,
);
},
then use it like this:
isApprovedLoading && selectedItem == index
? const CircularProgressIndicator(
color: constants.Colors.purpleMain)
: OrderButton(...),

Flutter || Checkbox on hover doesn't give on tap cursor permission

I am working on dropdownmenu items where in the drop-down menu item there are several checkboxes but any of the checkboxes on hover don't give on tap cursor permission.
This is a very strange thing I found out as I have already used the checkbox before but this type of error I didn't receive.
I think maybe the problem is in dropdownmenu.
I have also included the video for better understanding of my problem.
my code :-
Container(
width: 160,
//margin: const EdgeInsets.only(top: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5), color: Colors.white),
child: ListTileTheme(
contentPadding: EdgeInsets.all(0),
dense: true,
horizontalTitleGap: 0.0,
minLeadingWidth: 0,
child: ExpansionTile(
iconColor: primaryBackgroundLightGrey,
title: Text(
listOFSelectedItem.isEmpty
? "Project type"
: listOFSelectedItem[0],
style: t5O40),
children: <Widget>[
Container(
height: 10,
color: primaryBackgroundLightGrey,
),
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: widget.listOFStrings.length,
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
Container(
height: 10,
),
Container(
margin: const EdgeInsets.only(bottom: 8.0),
child: _ViewItem(
item: widget.listOFStrings[index],
selected: (val) {
selectedText = val;
if (listOFSelectedItem.contains(val)) {
listOFSelectedItem.remove(val);
} else {
listOFSelectedItem.add(val);
}
widget.selectedList(listOFSelectedItem);
setState(() {});
},
itemSelected: listOFSelectedItem
.contains(widget.listOFStrings[index])),
),
],
);
},
),
],
),
),
),
class _ViewItem extends StatelessWidget {
String item;
bool itemSelected;
final Function(String) selected;
_ViewItem(
{required this.item, required this.itemSelected, required this.selected});
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Padding(
padding: EdgeInsets.only(
left: size.width * .015,
),
child: Row(
children: [
SizedBox(
height: 2,
width: 2,
child: Checkbox(
value: itemSelected,
onChanged: (val) {
selected(item);
},
hoverColor: Colors.transparent,
checkColor: Colors.white,
activeColor: Colors.grey),
),
SizedBox(
width: size.width * .010,
),
Text(item, style: t3O60),
],
),
);
}
}
You can adapt the example to your own code
dropdownBuilder: _customDropDownExample,
popupItemBuilder: _customPopupItemBuilderExample,
Widget _customDropDownExample(
BuildContext context, UserModel? item, String itemDesignation) {
if (item == null) {
return Container();
}
return Container(
child: (item.avatar == null)
? ListTile(
contentPadding: EdgeInsets.all(0),
leading: CircleAvatar(),
title: Text("No item selected"),
)
: ListTile(
contentPadding: EdgeInsets.all(0),
leading: CircleAvatar(
// this does not work - throws 404 error
// backgroundImage: NetworkImage(item.avatar ?? ''),
),
title: Text(item.name),
subtitle: Text(
item.createdAt.toString(),
),
),
);
After that
Widget _customPopupItemBuilderExample(
BuildContext context, UserModel item, bool isSelected) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 8),
decoration: !isSelected
? null
: BoxDecoration(
border: Border.all(color: Theme.of(context).primaryColor),
borderRadius: BorderRadius.circular(5),
color: Colors.white,
),
child: ListTile(
selected: isSelected,
title: Text(item.name),
subtitle: Text(item.createdAt.toString()),
leading: CircleAvatar(
// this does not work - throws 404 error
// backgroundImage: NetworkImage(item.avatar ?? ''),
),
),
);
I am using this package https://pub.dev/packages/dropdown_button2
Multiselect Dropdown with Checkboxes
final List<String> items = [
'Item1',
'Item2',
'Item3',
'Item4',
];
List<String> selectedItems = [];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton2(
isExpanded: true,
hint: Align(
alignment: AlignmentDirectional.center,
child: Text(
'Select Items',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).hintColor,
),
),
),
items: items.map((item) {
return DropdownMenuItem<String>(
value: item,
//disable default onTap to avoid closing menu when selecting an item
enabled: false,
child: StatefulBuilder(
builder: (context, menuSetState) {
final _isSelected = selectedItems.contains(item);
return InkWell(
onTap: () {
_isSelected
? selectedItems.remove(item)
: selectedItems.add(item);
//This rebuilds the StatefulWidget to update the button's text
setState(() {});
//This rebuilds the dropdownMenu Widget to update the check mark
menuSetState(() {});
},
child: Container(
height: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
_isSelected
? const Icon(Icons.check_box_outlined)
: const Icon(Icons.check_box_outline_blank),
const SizedBox(width: 16),
Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
],
),
),
);
},
),
);
}).toList(),
//Use last selected item as the current value so if we've limited menu height, it scroll to last item.
value: selectedItems.isEmpty ? null : selectedItems.last,
onChanged: (value) {},
buttonHeight: 40,
buttonWidth: 140,
itemHeight: 40,
itemPadding: EdgeInsets.zero,
selectedItemBuilder: (context) {
return items.map(
(item) {
return Container(
alignment: AlignmentDirectional.center,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
selectedItems.join(', '),
style: const TextStyle(
fontSize: 14,
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
);
},
).toList();
},
),
),
),
);
}

Flutter showing null check operator used on a null value on app start up

I'm new to flutter, i'm trying to write a radio streaming app, i used just_audio to handle my player. When i start up my app on debug mode, it gives me the null check operator used on a null value message. I've tried adding a if condition to check if is null, but it didn't quite work.
Here's my widget code:
#override
Widget build(BuildContext context) {
return new WillPopScope(
onWillPop: () async => false,
child: new MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Container(
decoration: new BoxDecoration(
image: new DecorationImage(image: AssetImage("assets/img/MobilePlayer.png"), fit: BoxFit.cover),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: StreamBuilder<SequenceState?>(
stream: _player.sequenceStateStream,
builder: (context, snapshot) {
final state = snapshot.data;
if (state?.sequence.isEmpty ?? true) return SizedBox();
final metadata = state!.currentSource!.tag as AudioMetadata;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child:
Center(
child: Image.network(metadata.artwork,
scale: 1.5,
),
),
),
),
// Text(metadata.album,
// style: Theme.of(context).textTheme.headline6),
// Text(metadata.title),
],
);
},
),
),
ControlButtons(_player),
// StreamBuilder<PositionData>(
// stream: _positionDataStream,
// builder: (context, snapshot) {
// final positionData = snapshot.data;
// return SeekBar(
// duration: positionData?.duration ?? Duration.zero,
// position: positionData?.position ?? Duration.zero,
// bufferedPosition:
// positionData?.bufferedPosition ?? Duration.zero,
// onChangeEnd: (newPosition) {
// _player.seek(newPosition);
// },
// );
// },
// ),
SizedBox(height: 8.0),
Row(
children: [
],
),
Container(
height: 300.0,
color: Colors.transparent,
**child: StreamBuilder<SequenceState?>(**
stream: _player.sequenceStateStream,
builder: (context, snapshot) {
final state = snapshot.data;
final sequence = state?.sequence ?? [];
final metadata = state!.currentSource!.tag as AudioMetadata;
return ListView(
children: [
for (var i = 0; i < sequence.length; i++)
Dismissible(
key: ValueKey(sequence[i]),
background: Container(
color: Colors.transparent,
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(Icons.delete, color: Colors.transparent),
),
),
onDismissed: (dismissDirection) {
_playlist.removeAt(i);
},
child: Material(
color: i == state.currentIndex
? Colors.transparent
: Colors.transparent,
child: Card(
color: Colors.transparent,
shape: StadiumBorder(
side: BorderSide(
color: i == state.currentIndex
? Colors.yellow
: Colors.white,
width: 1.0,
),
),
child: ListTile(
title: Text(sequence[i].tag.title as String,
style: GoogleFonts.lato(
textStyle: TextStyle(color: i == state.currentIndex
? Colors.yellow
: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w700,
),
),
textAlign: TextAlign.center,
),
onTap: () {
_player.seek(Duration.zero, index: i);
},
leading: Wrap(
children: <Widget>[
IconButton(icon: i == state.currentIndex
? Icon(Icons.pause, color: i == state.currentIndex
? Colors.yellow
: Colors.white,)
: Icon(Icons.play_arrow,
color: i == state.currentIndex
? Colors.yellow
: Colors.white,),
onPressed: (){
_player.seek(Duration.zero, index: i);
i == state.currentIndex
? _player.pause()
: _player.play();
}
),
],
),
trailing: Wrap(
children: <Widget>[
IconButton(icon: Icon(FontAwesomeIcons.whatsapp,
color: i == state.currentIndex
? Colors.yellow
: Colors.white,),
onPressed: () async => await launch(sequence[i].tag.wpp as String)
)
],
),
),
),
),
),
],
);
},
),
),
],
),
),
),
),
);
}
this is a common problem in Flutter, this error means that you have marked a variable that will never be null with this ! mark. but while your program is running this value has become null.
In your code, you have used ! this mark in multiple lines. simply, place a debug pointer there and identify when this becomes null.
also, you should use the below method whenever possible.
String hello = state?.value ?? 'default';
instead of this:
String hello = state!.value
When you use a StreamBuilder, make sure you check if you already have the data before you try to work with it:
if (!snapshot.hasData) return CircularProgressIndicator();
You get a null error because you try to use the variable before the StreamBuilder put some data in it, so it is still null... But with the ! mark you say that "don't worry about this variable, when the code gets here I make sure it is not null"

Flutter problem with saving the value from document from database to a initState value

I have a problem with fetching value from database document to a variable called in initState method. When I am doing that there is a problem with null value and I think that get() method from Firebase is taking the value too late(it happens when i reload the scene).
bool _dark;
bool options;
MainModel model;
final MyUser myUser;
final UserSettings userSettings;
_SettingsOnePageState(this.userSettings, this.myUser);
final user = FirebaseAuth.instance.currentUser;
#override
void initState() {
super.initState();
// _dark = false;
FirebaseFirestore.instance
.collection("settings")
.doc(user.uid)
.get()
.then((value) {
print(value.data()['darkMode']);
_dark = value.data()['darkMode'];
});
options = false;
}
Brightness _getBrightness() {
return _dark ? Brightness.dark : Brightness.light;
}
#override
Widget build(BuildContext context) {
return Theme(
// return StreamProvider<QuerySnapshot>.value(
isMaterialAppTheme: true,
data: ThemeData(
brightness: _getBrightness(),
),
// value: SettingsUser().settings,
child: StreamBuilder<UserSettings>(
//setting the stream for settings from database
stream: DatabaseUser(userId: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
//data for user from database
UserSettings userSettings = snapshot.data;
// _dark = userSettings.darkMode;
// print("dark mode " + userSettings.darkMode.toString());
return Form(
key: _formKey,
child: Scaffold(
backgroundColor: _dark ? null : Colors.grey.shade200,
appBar: AppBar(
//elevation: 10,
brightness: _getBrightness(),
iconTheme: IconThemeData(
color: _dark ? Colors.white : Colors.black),
backgroundColor: Colors.transparent,
title: Text(
'Change theme',
style: TextStyle(
color: _dark ? Colors.white : Colors.black),
textAlign: TextAlign.center,
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.auto_awesome),
onPressed: () {
setState(() {
_dark = !_dark;
});
},
)
],
),
body: Stack(fit: StackFit.expand, children: <Widget>[
SingleChildScrollView(
//padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Text(
userSettings.nick,
textScaleFactor: 4,
style: TextStyle(
color: _dark
? Colors.white
: Colors.purple[500],
//fontWeight: FontWeight.w500,
),
)),
const SizedBox(height: 50.0),
],
),
Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Container(
// width: 200,
// height: 200,
child: CircleAvatar(
radius: 100.0,
backgroundImage:
//NetworkImage(user.photoURL),
NetworkImage(
userSettings.pictureUrl),
),
),
),
],
),
//const SizedBox(height: 20.0),
if (options == true) ...[
//SettingsEdit(),
//NickChange(),
ImageInput(),
],
const SizedBox(height: 10.0),
Card(
elevation: 4.0,
margin: const EdgeInsets.fromLTRB(
32.0, 8.0, 32.0, 16.0),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.0)),
child: Column(
children: <Widget>[
ListTile(
leading: Icon(
Icons.account_box,
color: Colors.purple,
),
title: Text("Change Nickname"),
trailing:
Icon(Icons.keyboard_arrow_right),
onTap: () {
//open change nick
//changeNick();
},
),
_buildDivider(),
ListTile(
leading: Icon(
Icons.add_a_photo,
color: Colors.purple,
),
title: Text("Change Photo"),
trailing:
Icon(Icons.keyboard_arrow_right),
onTap: () {
//open change photo
//changePhoto();
},
),
_buildDivider(),
ListTile(
leading: Icon(
Icons.lock_rounded,
color: Colors.purple,
),
title: Text("Change Password"),
trailing:
Icon(Icons.keyboard_arrow_right),
onTap: () {
//open change password
//changePassword();
},
),
_buildDivider(),
ListTile(
leading: Icon(
Icons.location_on,
color: Colors.purple,
),
title: Text("Change Your Location"),
trailing:
Icon(Icons.keyboard_arrow_right),
onTap: () {
//open change location
},
),
],
),
),
const SizedBox(height: 20.0),
]))
])));
}
return Scaffold();
}));
}
debug console
settings where I use theme now
Do you know how to avoid this null in initState? I am trying to change theme of the app and I am taking that from Firebase document whick I created when the user registered. Than I will be changing it in user settings and also want to use it(this theme) in whole app.
Thanks for help
InitState is not async (meaning execution doesn't wait for your firebase call to complete). This means that your view will be rendered before you assign _dark a value.
If you want to wait until that call is complete, use something called FutureBuilder.

List.Builder giving range error in Flutter

I have added my entire code over here. The getRecords method takes more time to add to the lists and hence my list returns empty at first and so listbuilder fails giving range error and that only range accepted is 0. BTW, Its a Todo app.
InitState :
void initState() {
super.initState();
setState(() {
getRecords();
});
}
Getting from the database
void getRecordsAndDisplay() async {
final records = await Firestore.instance.collection('tasks').getDocuments();
for (var record in records.documents) {
if (record.data['phone'] == '1') {
int len = record.data['task'].length;
if (len != null || len != 0) {
for (int i = 0; i < len; i++) {
String temp = record.data['task'][i];
tasks.add(temp);
}
}
else
continue;
}
else
continue;
}
setState(() {
listView = ListView.builder(
scrollDirection: Axis.vertical,
itemCount: tasks.length,
itemBuilder: (BuildContext context,int index) {
return Container(
margin: EdgeInsets.only(bottom: 10.0),
decoration: BoxDecoration(
color: Colors.deepPurple[700],
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
child: ListTile(
onTap: (){},
leading: IconButton(
icon: Icon(Icons.delete),
iconSize: 25.0,
color: Colors.white,
onPressed: () {
setState(() {
tasks.removeAt(index);
checkValue.removeAt(index);
updateValue();
});
},
),
title: Text(
'${tasks[index]}',
style: TextStyle(
fontSize: 18.0,
color: Colors.white,
fontWeight: FontWeight.bold,
decoration: checkValue[index]
? TextDecoration.lineThrough
: null,
),
),
trailing: Checkbox(
value: checkValue[index],
activeColor: Colors.white,
checkColor: Colors.deepPurple[700],
onChanged: (bool value) {
setState(() {
checkValue[index] = !checkValue[index];
});
},
),
),
);
},
);
});
}
Scaffold:
return Scaffold(
backgroundColor: Color(0xff8780FF),
body: SafeArea(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
colors: [Colors.deepPurple[400], Color(0xff6B63FF)])),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(30.0, 30.0, 30.0, 15.0),
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
spreadRadius: 1.0,
blurRadius: 50.0,
),
]),
child: Icon(
Icons.list,
color: Colors.white,
size: 30.0,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
padding: EdgeInsets.only(
bottom: 20.0,
left: 30.0,
),
child: Text(
'Todo List',
style: TextStyle(
color: Colors.white,
fontSize: 35.0,
fontWeight: FontWeight.w900,
),
),
),
Expanded(
child: SizedBox(
width: 20.0,
),
),
IconButton(
padding: EdgeInsets.only(
right: 10.0,
bottom: 20.0,
),
icon: Icon(Icons.add),
iconSize: 30.0,
color: Colors.white,
onPressed: () async {
final resultText = await showModalBottomSheet(
context: context,
builder: (context) => AddTaskScreen(),
isScrollControlled: true);
setState(() {
tasks.add(resultText);
checkValue.add(false);
Firestore.instance
.collection('tasks')
.document('1')
.updateData({
'task': FieldValue.arrayUnion([resultText]),
});
});
},
),
IconButton(
padding: EdgeInsets.only(
right: 10.0,
bottom: 20.0,
),
icon: Icon(Icons.delete_outline),
iconSize: 30.0,
color: Colors.white,
onPressed: () {
setState(() {
tasks.clear();
checkValue.clear();
Firestore.instance
.collection('tasks')
.document('1')
.updateData({
'task': null,
});
});
},
),
],
),
],
),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 10.0, right: 10.0),
height: MediaQuery.of(context).size.height,
child: listView,
),
),
],
),
),
),
);
Please help me out. I am stuck with this for a long time :(
the problem is that in initstate you cannot await for async methods so you should implement a StreamBuilder that wraps your listview..
A streambuilder is a widget that takes a stream and waits for the call completition then when the data is ok shows a widget -> your listview
A little example
StreamBuilder(
stream: YOUR_ASYNC_CALL_THAT_RETURN_A_STREAM,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container(
alignment: Alignment.center,
child: Text(
"NO ITEMS"
),
);
}
else {
var yourList = snapshot.data.documents;//there you have to do your implementation
return ListView.builder(
itemBuilder: (context, index) => buildItem(index,yourList[index]),
itemCount: yourList.length,
);
}
},
),