How to get back a value from a customly created widget in Flutter - flutter

I am showing a showModalBottomSheet using a function. I want that as soon as it closes, value of a variable should change. I wanted to change value of two variables, but I am not able to change for even one. Please help me with this. I tried to make my own onChanged and also tried to return the value using function, but nothing happens.
This is the function, please scroll to the last of it and check out the onTap function and return.
String showChapterSelectionSheet(
BuildContext context,
List<ChapterModel> chapter_list,
String chapter_name,
final Function(String) onChapterChanged) {
String retValue = chapter_name;
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
elevation: 0,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20)),
),
builder: (context) {
return StatefulBuilder(
builder: (BuildContext context,
StateSetter setState /*You can rename this!*/) {
return makeDismissible(
context,
child: DraggableScrollableSheet(
initialChildSize: 0.81,
minChildSize: 0.5,
maxChildSize: 0.81,
builder: (_, controller) => Container(
padding: EdgeInsets.all(getProportionateScreenWidth(25)),
height: getProportionateScreenWidth(600),
decoration: BoxDecoration(
color: backgroundColor2,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(
top: getProportionateScreenHeight(32),
bottom: getProportionateScreenHeight(16)),
child: Text(
AppLocalizations.of(context)!.chapters,
style: Theme.of(context)
.textTheme
.headline2!
.apply(color: Colors.white),
),
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
controller: controller,
itemCount: chapter_list.length,
itemBuilder: (_, index) {
return GestureDetector(
child: Padding(
padding: EdgeInsets.only(
top: getProportionateScreenHeight(8)),
child: Card(
child: Container(
height: getProportionateScreenHeight(56),
width: getProportionateScreenWidth(341),
decoration: BoxDecoration(
border: Border.all(color: cardColor),
color: chapter_list[index].chapter_name! ==
chapter_name
? backgroundColor
: cardColor,
),
child: Padding(
padding: EdgeInsets.all(0),
child: Center(
child: Row(
children: [
Container(
width:
getProportionateScreenWidth(
32),
child: chapter_list[index]
.chapter_name! ==
chapter_name
? Icon(
Icons.check,
color: brandYellow,
)
: SizedBox()),
Text(
"Chapter ${chapter_list[index].position!}: ",
style: Theme.of(context)
.textTheme
.bodyText2!
.apply(color: brandYellow),
),
Expanded(
child: Text(
chapter_list[index]
.chapter_name!,
style: Theme.of(context)
.textTheme
.bodyText2!
.apply(
color: chapter_list[
index]
.chapter_name! ==
chapter_name
? tertiaryTextColor
: primaryTextColor)),
),
],
),
),
),
),
),
),
onTap: () {
onChapterChanged(chapter_list[index].chapter_name!);
setState(() {
retValue = chapter_list[index].chapter_name!;
});
Navigator.pop(context);
},
);
},
),
),
],
),
),
),
);
},
);
},
);
return retValue;
}
And I am accessing it here -
return InkWell(
onTap: () async {
if(dataList.isNotEmpty) {
chapterName.value = showChapterSelectionSheet(
context,dataList,chapterName.value,(val) {
setState(() {
chapterName.value = val;
print("Val is - $val");
});
}
);
}
},
child: .....
);
In the above InkWell, the print statement is working fine but value is not changing.
And I want to update and use the value here -
child: ValueListenableBuilder(
valueListenable: chapterName,
builder: (context, String val, Widget? child) {
return Text(
val,
style: TextStyle(
color: Colors.white,
fontSize: 15,
),
);
},
),

It is possible you are just missing await before await showModalBottomSheet(..).
You can follow this simplified snippet.
class BVChange extends StatefulWidget {
const BVChange({Key? key}) : super(key: key);
#override
State<BVChange> createState() => _BVChangeState();
}
class _BVChangeState extends State<BVChange> {
String var1 = "Old", var2 = "old1";
Future<String> _showDialog(String v) async {
double _sliderValue = 0.0;
await showModalBottomSheet(
context: context,
builder: (_) {
return StatefulBuilder(
builder: (context, sbSate) => Column(
children: [
Text(_sliderValue.toString()),
Slider(
value: _sliderValue,
onChanged: (sval) {
sbSate(() {
_sliderValue = sval;
});
}),
],
),
);
});
return _sliderValue.toString();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
GestureDetector(
onTap: () async {
final data = await _showDialog(var1);
setState(() {
var1 = data;
});
},
child: Text("var1 : $var1")),
GestureDetector(
onTap: () async {
final data = await _showDialog(var2);
setState(() {
var2 = data;
});
},
child: Text("var 2 : $var2"),
),
],
),
);
}
}

Related

How to return data from custom function which uses bottom sheet in flutter

I made a custom function which opens modal bottom sheet in flutter. Now, I want to get some data back from the sheet to my previous page. How should I do it? I tried to make function's return type as Future<FilterDataModel> and Future, but it's not working. I want that whenever the user clicks on cancel, it should return false and when he presses apply, i should get true with the data.
Here is what I tried -
Future<FilterDataModel> showFilterBottomSheet<T>(
{required BuildContext context}) async {
Some code ...........
FilterDataModel filterData = FilterDataModel();
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
String val = "One";
return StatefulBuilder(
builder: (context, StateSetter setState) {
return Wrap(
children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: getProportionateScreenHeight(20),
horizontal: getProportionateScreenWidth(16),
),
child: Column(
..............
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: InkWell(
onTap: () {
Navigator.pop(context, [false, filterData]);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.white),
),
padding: EdgeInsets.symmetric(
vertical: getProportionateScreenHeight(16),
),
child: Center(
child: Text(
'Cancel',
style: TextStyle(
color: primaryText2,
fontSize: 16,
),
),
),
),
),
),
SizedBox(
width: getProportionateScreenWidth(20),
),
Expanded(
child: InkWell(
onTap: () {
Navigator.pop(context, [true, filterData]);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.black38),
),
padding: EdgeInsets.symmetric(
vertical: getProportionateScreenHeight(16),
),
child: Center(
child: Text(
'Apply',
style: TextStyle(
color: primaryOrange,
fontSize: 16,
),
),
),
),
),
),
],
),
],
),
),
],
);
},
);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
).then((value) {
debugPrint("Coming data");
debugPrint(filterData.academicYear.toString());
return filterData;
});
return filterData;
}
And how I am calling it -
onPressed: () async {
FilterDataModel f = await showFilterBottomSheet(
context: context,
);
print("Here - ${f.academicYear}");
},
I also tried to do it like this -
onPressed: () async {
await showFilterBottomSheet(
context: context,
).then((value) {
print("Inside then");
print(value[0]);
print(value[1].toString());
});
print("Here - ${f.academicYear}");
},
But it's not working.
You need to await your bottom sheet, to get the result that was returned from the Navigator.pop(context, value). so it will be like.
final res = await showModalBottomSheet(context, ....);
/// this is to make sure that the Navigator.pop(context) from the bottom sheet did not return a null.
if (res != null) {
FilterDataModel filterData = FilterDataModel();
return filterData;
} else {
return anything;
}
looks like when you pop navigator you return List< dynamic> (boolean + filterDataModel)
so the scheme is:
final result = await showModalBottomSheet<dynamic>(){
...
...
return YourWidget(
...
onTap: ()=> Navigator.of(context).pop([false, filterDataModel])
...
)
}
final boolResult = result[0] as boolean;
final dataResult = result[1] as FilterDataModel;`
take a note that if modal is dismissible then return will be null in case it is dismissed without returned value and you will have to handle this case also

showModalBottomSheet rounded corner

I am facing strange issue in showModalBottomSheet. Rounded corner is not working. Please see the code. But ff I add the Text('Title') before Expanded widget, it is showing rounded corner.
But I can't add the title here because DownloadedDharmaSongScreen has AppBar.
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(_radius),
topRight: Radius.circular(_radius),
),
),
builder: (BuildContext context) {
return DraggableScrollableSheet(
initialChildSize: 0.9,
expand: false,
builder: (context, scrollController) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: DownloadedDharmaSongScreen(
controller: scrollController,
destinationFavourite: widget.destinationFavourite,
sourceFavourite: favourite,
socialMode: widget.socialMode,
),
),
const SizedBox(
height: 60,
)
],
);
},
);
},
);
DownloadedDharmaSongScreen
class DownloadedDharmaSongScreen extends StatefulWidget {
static const routeName = '/downloaded_dharma_song';
final ScrollController? controller;
final Favourite? destinationFavourite;
final Favourite? sourceFavourite;
final SocialMode socialMode;
const DownloadedDharmaSongScreen({
Key? key,
this.controller,
this.destinationFavourite,
this.sourceFavourite,
required this.socialMode,
}) : super(key: key);
#override
State<DownloadedDharmaSongScreen> createState() =>
_DownloadedDharmaSongScreen();
}
class _DownloadedDharmaSongScreen extends
State<DownloadedDharmaSongScreen> {
List<FavouriteSong> favouriteSongs = [];
List<FavouriteSong> selectedFavouriteSongs = [];
bool isSelected = false;
_loadDownloadFiles() async {
BlocProvider.of<FavouriteSongBloc>(context).add(
GetAllDownloadedSongsByFavouriteId(
favouriteId: widget.sourceFavourite!.id!));
}
#override
void initState() {
super.initState();
_loadDownloadFiles();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar(
centerTitle: true,
backgroundColor: Theme.of(context).backgroundColor,
elevation: 0,
title: AutoSizeText(
widget.sourceFavourite!.name,
style: Theme.of(context).appBarTheme.titleTextStyle,
),
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(
Icons.arrow_back,
color: Theme.of(context).primaryIconTheme.color!,
),
),
actions: [
Container(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
CupertinoButton(
minSize: double.minPositive,
padding: const EdgeInsets.only(right: 5),
child: Icon(Icons.done,
color: selectedFavouriteSongs.isNotEmpty
? Theme.of(context).primaryIconTheme.color!
: Theme.of(context).disabledColor),
onPressed: selectedFavouriteSongs.isNotEmpty
? () {
BlocProvider.of<FavouriteSongBloc>(context).add(
AddSelectedSongs(
favourite: widget.destinationFavourite!,
favouriteSongs: selectedFavouriteSongs,
socialMode: widget.socialMode));
}
: null,
),
],
),
)
],
),
body: BlocListener<FavouriteSongBloc, FavouriteSongState>(
listener: (context, state) {
if (state is SelectedFavouriteSuccess) {
Navigator.of(context).pop();
}
},
child: BlocBuilder<FavouriteSongBloc, FavouriteSongState>(
builder: (context, state) {
if (state is SongError) {
return const SomethingWentWrongScreen();
} else if (state is DownloadedSongListLoaded) {
if (state.favouriteSongs.isEmpty) {
return const NoResultFoundScreen(
title: 'သိမ်းထားသေားတရားတော်များ မရှိသေးပါ။',
subTitle:
'ကျေးဇူးပြု၍ တရားတော်များကို အစီအစဉ်စာရင်းထဲသို့ ထည့်ပါ။',
);
}
favouriteSongs = state.favouriteSongs;
return ListView.separated(
separatorBuilder: (BuildContext context, int index) =>
const Divider(height: 1),
itemCount: state.favouriteSongs.length,
itemBuilder: (_, int index) {
return Material(
child: ListTile(
minLeadingWidth: 0,
onTap: () {
setState(() {
favouriteSongs[index].isSelected =
!favouriteSongs[index].isSelected;
if (favouriteSongs[index].isSelected == true) {
selectedFavouriteSongs.add(favouriteSongs[index]
.copyWith(isSelected: true));
} else if (favouriteSongs[index].isSelected ==
false) {
selectedFavouriteSongs.removeWhere((element) =>
element.id == favouriteSongs[index].id);
}
});
},
title: TitleWidget(
favouriteSong: favouriteSongs[index],
),
subtitle:
SubTitleWidget(favouriteSong: favouriteSongs[index]),
trailing: favouriteSongs[index].isSelected
? Icon(
Icons.check_circle,
color: Theme.of(context).primaryColor,
)
: const Icon(Icons.check_circle_outline),
),
);
},
);
}
return const CircularProgressIndicatorWidget();
},
),
),
);
}
}
You can wrap DraggableScrollableSheet with ClipRRect with providing borderRadius.
builder: (BuildContext context) {
return ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(_radius),
topRight: Radius.circular(_radius),
),
child: DraggableScrollableSheet(
This issue is coming from builder inner views, here it is from DownloadedDharmaSongScreen, You can also wrap it with ClipRRect instead of using it on builder.
builder: (context, scrollController) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(_radius),
topRight: Radius.circular(_radius),
),
child:DownloadedDharmaSongScreen(

BottomSheet value does not update using button flutter

I have a Bottom Sheet which has sets of buttons. I use the buttons to change the value of pinString and a text to show the pinString. The value of the text does not update when button is clicked. How to fix this
showNumberPad(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (context) {
return StatefulBuilder(builder: (context, setState) {
return Container(
height: 550.0,
child: Column(
children: <Widget>[
Text(
"$pinString",
),
KeyboardNumber(
n: 1,
onPressed: () {
pinIndexSetup("1");
setState1() {
pinString = "New Pin";
}
},
),
],
),
);
});
},
);
}
KeyboardNumber is a custom Stateful widget where I want to pass the onPressed as a parameter.
Code for keyboardNumber:
class KeyboardNumber extends StatefulWidget {
final int n;
final onPressed;
const KeyboardNumber({Key key, this.n, this.onPressed}) : super(key: key);
#override
_KeyboardNumberState createState() => _KeyboardNumberState();
}
class _KeyboardNumberState extends State<KeyboardNumber> {
#override
Widget build(BuildContext context) {
return Container(
width: 60.0,
height: 60.0,
decoration: BoxDecoration(
color: teal2,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
alignment: Alignment.center,
child: FlatButton(
padding: EdgeInsets.all(8.0),
onPressed: widget.onPressed,
height: 90.0,
child: Text(
"${widget.n}",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}
}
you define pinString in another state and change it in bottomeSheet state, you must define it in this line :
showModalBottomSheet(
context: context,
builder: (context) {
String pinString = 'hi';
return StatefulBuilder(builder: (BuildContext context, StateSetter setState){
return Container(
height: 550.0,
child: Column(
children: <Widget>[
Text(
"$pinString",
),
FlatButton(
child: Text("Update"),
onPressed: () {
setState(() => pinString = 'new');
},
),
],
),
);
});
},
);
}
Please note that the new setState will override your main widget setState but sure you can just rename it so you would be able to set state of your parent widget and the modal's
Here is the updated code.
showNumberPad(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (context) {
return StatefulBuilder(builder: (context, SetState1) {
return Container(
height: 550.0,
child: Column(
children: <Widget>[
Text(
"$pinString",
),
FlatButton(
child: Text("Update"),
onPressed: () {
SetState1(() {
pinString = "New Pin";
});
},
),
],
),
);
});
},
);
}

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 Firebase: not able update Database

I want to update my Collection with an NumberPicker in a Alert Dialog. I do not get any errors in code or from the emulator. When i press the button to update the code the terminal do not give any errors. Everything looks fine but for some reason i do not work. When you need more Information just leave a comment with what you excactly need. :)
import 'package:flutter/material.dart';
import 'package:numberpicker/numberpicker.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
import 'package:testapp/services/Services.dart';
import 'models/Goals.dart';
class Statistics extends StatefulWidget {
#override
_StatisticsState createState() => _StatisticsState();
}
class _StatisticsState extends State<Statistics> {
int _currentFirstValue = 1;
int totalFirst;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 260,
child: StreamBuilder(
stream: FirestoreService().getGoals(),
builder: (context, AsyncSnapshot<List<Goal>> snapshot) {
if (snapshot.hasError || !snapshot.hasData) {
return Center(child: CircularProgressIndicator(
backgroundColor: Color(0XFF1954A1),
));
}
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
// ignore: missing_return
Goal goal = snapshot.data[index];
return Row(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
height: 230,
width: 350,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.grey[300],
offset: const Offset(0.5, 1),
blurRadius: 4.0,
spreadRadius: 0.1,
),
]),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text('WeekGoals', style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w500,
),),
SizedBox(width: 100),
SizedBox(
height: 20,
width: 87,
child: FlatButton(
child: Text('edit', style: TextStyle(
fontSize: 17,
color: Colors.yellow[700]
),),
onPressed: () {
return showDialog(
context: context,
barrierDismissible: true,
builder: (context) => AlertDialog(
content: Column(
children: <Widget>[
Text('weekly goals'),
NumberPicker.integer(
initialValue: _currentFirstValue,
minValue: 1,
maxValue: 100,
onChanged: (newGoal) => setState(() => {
_currentFirstValue = newGoal,
totalFirst = _currentFirstValue,
})
),
Row(
children: <Widget>[
RaisedButton(
child: Text('edit goals'),
onPressed: () async {
Goal goal = Goal(
weekActivityGoal: totalFirst,
);
await FirestoreService().updateGoal(goal);
Navigator.pop(context, false);
},
),
FlatButton(
child: Text('Close'),
onPressed: () {
Navigator.pop(context, false);
},
)
],
)
],
),
)
);
},
),
)
],
),
SizedBox(height: 10),
Row(
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 17.5),
child: CircularPercentIndicator(
header: Text('activitys', style: TextStyle(
fontSize: 17,
),),
radius: 130,
progressColor: Colors.red,
lineWidth: 8,
backgroundColor: Colors.grey[200],
percent: goal.weekActivity*100/goal.weekActivityGoal,
center: Text('${goal.weekActivity}/${goal.weekActivityGoal}'),
),
),
],
),
],
),
),
],
);
});
}),
),
);
}
}
Here this has been helping a lot of people try i out might help you too.
StreamBuilder(
stream: Firestore.instance.collection('Hearings').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) return Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Select lot');
case ConnectionState.waiting:
return Text('Awaiting bids...');
case ConnectionState.active:
{
print('active');
return Text('${snapshot.data}');
}
case ConnectionState.done:
{
print('Done');
return _buildList(context, snapshot.data);
}
}
return null;
}),
));
}
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
return ListView(
padding: const EdgeInsets.only(top: 20.0),
children: snapshot.map((data) => _buildListItem(context, data)).toList(),
);
}
Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
final record = Record.fromSnapshot(data);
return Padding(
key: ValueKey(record.name),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: ListTile(
title: Text(record.name),
trailing: Text(record.votes.toString()),
onTap: () => Firestore.instance.runTransaction((transaction) async {
final freshSnapshot = await transaction.get(record.reference);
final fresh = Record.fromSnapshot(freshSnapshot);
await transaction
.update(record.reference, {'votes': fresh.votes + 1});
}),
),
),
);
}
}
class Record {
final String name;
final int votes;
final DocumentReference reference;
Record.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['name'] != null),
assert(map['votes'] != null),
name = map['name'],
votes = map['votes'];
Record.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
#override
String toString() => "Record<$name:$votes>";
}
This is where the link this info came from.