Flutter create new instance of class on button tap and update values - flutter

I am creating a feature for users to be able to add occasions (title and date) to a list in Flutter. I have set up the features but i'm struggling to understand how to firstly, create a new instance of my DateToRemember class when my "add button" is pressed and then, when a title text value is entered, and a date selected from my datepicker, update that instance with those values. Then users will be able to click a submit button and their list updated.
Here is my date to remember model:
class DateToRemember {
String title;
DateTime date;
DateToRemember(this.title, this.date);
}
And the datestoremember page code:
class DatesToRemember extends StatefulWidget {
#override
_DatesToRememberState createState() => _DatesToRememberState();
}
class _DatesToRememberState extends State<DatesToRemember> {
TextEditingController _titleController = new TextEditingController();
DateTime startDate = DateTime.now();
DateTime pickedDate = DateTime.now();
DateFormat formatter = DateFormat('dd/MM/yyyy');
_DatesToRememberState();
Future displayDatePicker(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: startDate,
firstDate: startDate,
lastDate: DateTime(DateTime.now().year + 100));
if (picked != null)
setState(() {
pickedDate = picked;
print(DateFormat('dd/MM/yyyy').format(pickedDate).toString());
});
}
final List<DateToRemember> occasions = [
DateToRemember("Occasion 1", DateTime.now()),
DateToRemember("Occasion 2", DateTime.now()),
DateToRemember("Occasion 3", DateTime.now()),
];
String input;
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: GestureDetector(
onTap: () => Navigator.pop(context),
child: Icon(Icons.arrow_back)),
title: Text('Dates to Remember'),
),
backgroundColor: Colors.white,
body: Center(
child: Column(children: [
SizedBox(
height: 10.0,
),
Container(
width: MediaQuery.of(context).size.width * 0.8,
child: Text(
"It can be difficult to ",
style: TextStyle(fontFamily: FontNameDefault),
),
),
SizedBox(
height: 50.0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.centerRight,
child: FloatingActionButton(
backgroundColor: kPrimaryColor,
child: Icon(Icons.add),
onPressed: () {
// CREATE NEW INSTANCE OF DATETOREMEMBER CLASS
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Add occasion'),
content: Container(
height: 150.0,
child: Column(
children: [
TextField(
decoration: InputDecoration(
hintText: 'Occasion Title'),
//UPDATE TITLE IN CLASS WITH INPUT
//
),
TextField(
decoration: InputDecoration(
hintText: 'Pick Date'),
onTap: () async {
await displayDatePicker(context);
//SELECT DATE AND UPDATE INSTANCE OF CLASS
},
),
FlatButton(
child: Text('Submit'),
onPressed: () {
//Navigator.of(context).pop();
},
),
],
),
),
);
});
}),
),
),
Container(
height: MediaQuery.of(context).size.height * 0.6,
width: MediaQuery.of(context).size.width * 0.9,
decoration:
BoxDecoration(border: Border.all(color: Colors.black26)),
child: occasions.isEmpty
? Center(
child: Text(
'Add an occasion',
style: TextStyle(color: Colors.black),
))
: ListView.builder(
itemCount: occasions.length,
itemBuilder: (BuildContext context, int index) {
return Dismissible(
direction: DismissDirection.endToStart,
onDismissed: (direction) {
occasions.removeAt(index);
Scaffold.of(context).showSnackBar(new SnackBar(
content: Text('Occasion Removed'),
duration: Duration(seconds: 5),
));
},
key: UniqueKey(),
child: Card(
elevation: 8.0,
margin: EdgeInsets.all(8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: ListTile(
title: Text(occasions[index].title),
subtitle: Text(DateFormat('dd/MM/yyyy')
.format(occasions[index].date)
.toString()),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.red,
),
onPressed: () {
setState(() {
occasions.removeAt(index);
Scaffold.of(context)
.showSnackBar(new SnackBar(
content: Text('Occasion Removed'),
duration: Duration(seconds: 5),
));
});
},
),
),
),
);
}),
)
]),
));
}
}
I'm still a flutter/dart novice so not entirely sure if what i'm asking is the best way to achieve what I want, so open to new ideas also. Thanks.

Related

I have a List of Widgets and I want to update the properties of a specific widget inside the List

I have Created a list and an Add Button When user clicks on ADD button a widget is Created and Added to the Widget List.
Image of Output which has list of Predefined widgets on the left and an instance of that widget is created and shown on the right side when user clicks on Add Button : -
Now I want to edit the properties of those widgets on the right .For example making the text Bold or Add value to textfield or changing the Text on the Button or defining what happens on onPressed event dynamically
Here is the code for Both the classes
PredfinedFileds.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class PreDefinedFields{
static Text textCustom= Text("New Text");
static TextFormField textFieldCustom= TextFormField(
);
static ElevatedButton elevatedButtonCustom= ElevatedButton(onPressed: (){}, child: Text("New Button"));
}
CustomizableForm.dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'PreDefinedFields.dart';
class CustomizableForm extends StatefulWidget {
const CustomizableForm({Key? key}) : super(key: key);
#override
State<CustomizableForm> createState() => _CustomizableFormState();
}
class _CustomizableFormState extends State<CustomizableForm> {
static bool isBold=false;
List fieldList=[];
List widgetList=[];
var text;
#override
Widget build(BuildContext context) {
void ShowDilogText(isBold){
showGeneralDialog(
context: context,
barrierLabel: "Barrier",
barrierDismissible: true,
barrierColor: Colors.black.withOpacity(0.5),
transitionDuration: Duration(milliseconds: 700),
pageBuilder: (_, __, ___) {
return Center(
child: Container(
height: 440,
width: MediaQuery.of(context).size.width/2,
child: SizedBox(child: Container(
child: Center(child: ElevatedButton(
onPressed: (){
isBold != isBold;
},
child: Text("Bold"),
),),
)),
margin: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(40)),
),
);
},
transitionBuilder: (_, anim, __, child) {
Tween<Offset> tween;
if (anim.status == AnimationStatus.reverse) {
tween = Tween(begin: Offset(-1, 0), end: Offset.zero);
} else {
tween = Tween(begin: Offset(1, 0), end: Offset.zero);
}
return SlideTransition(
position: tween.animate(anim),
child: FadeTransition(
opacity: anim,
child: child,
),
);
},
);
}
TextEditingController dateController= TextEditingController();
TextField datePickerField=TextField(
controller: dateController, //editing controller of this TextField
decoration: const InputDecoration(
icon: Icon(Icons.calendar_today), //icon of text field
labelText: "Enter Date" //label text of field
),
readOnly: true, // when true user cannot edit text
onTap: () async {
//when click we have to show the datepicker
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: DateTime.now(), //get today's date
firstDate:DateTime(2000), //DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2101)
);
if(pickedDate != null ){
print(pickedDate); //get the picked date in the format => 2022-07-04 00:00:00.000
String formattedDate = DateFormat('yyyy-MM-dd').format(pickedDate); // format date in required form here we use yyyy-MM-dd that means time is removed
print(formattedDate); //formatted date output using intl package => 2022-07-04
//You can format date as per your need
setState(() {
dateController.text = formattedDate; //set foratted date to TextField value.
});
}else{
print("Date is not selected");
}
}
);
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Row(
children: [
//For Predefined Fields
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: MediaQuery.of(context).size.width/3,
child: Column(
children: [
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text("Text"),
trailing: ElevatedButton(onPressed: (){
fieldList.add('Text');
widgetList.add(PreDefinedFields.textCustom);
setState(() {
print(fieldList);
});
}, child: Text("+ Add")),
),
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text("Text Field"),
trailing: ElevatedButton(onPressed: (){
fieldList.add('TextField');
widgetList.add(PreDefinedFields.textFieldCustom);
setState(() {
print(fieldList);
});
}, child: Text("+ Add")),
),
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text("Button"),
trailing: ElevatedButton(onPressed: (){
fieldList.add('Button');
widgetList.add(PreDefinedFields.elevatedButtonCustom);
setState(() {
print(fieldList);
});
}, child: Text("+ Add")),
),
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text("Date"),
trailing: ElevatedButton(onPressed: (){
fieldList.add('Date Picker');
widgetList.add(datePickerField);
setState(() {
print(fieldList);
});
}, child: Text("+ Add")),
),
],
),
),
),
//For Form
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
height: MediaQuery.of(context).size.height-50,
width: MediaQuery.of(context).size.width/2,
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent)
),
child: Form(
child: ListView.builder(
shrinkWrap: true,
itemCount: fieldList.length,
itemBuilder: (context,index){
if(fieldList[index]=='Text'){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
PreDefinedFields.textCustom,
Spacer(),
IconButton(onPressed: (){
ShowDilogText(isBold);
setState(() {
final tile = widgetList.firstWhere((item) => item[index]);
});
}, icon: Icon(Icons.edit)),
IconButton(onPressed: (){
}, icon: Icon(Icons.delete,color: Colors.red,))
],
),
);
}
if(fieldList[index]=='Date Picker'){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
SizedBox(
width: 400,
child: datePickerField),
Spacer(),
IconButton(onPressed: (){}, icon: Icon(Icons.edit)),
IconButton(onPressed: (){}, icon: Icon(Icons.delete,color: Colors.red,))
],
),
);
}
if(fieldList[index]=='TextField'){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
SizedBox(
width: 400,
child: PreDefinedFields.textFieldCustom),
Spacer(),
IconButton(onPressed: (){}, icon: Icon(Icons.edit)),
IconButton(onPressed: (){}, icon: Icon(Icons.delete,color: Colors.red,))
],
),
);
}
if(fieldList[index]=='Button'){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
PreDefinedFields.elevatedButtonCustom,
Spacer(),
IconButton(onPressed: (){}, icon: Icon(Icons.edit)),
IconButton(onPressed: (){}, icon: Icon(Icons.delete,color: Colors.red,))
],
),
);
}
return Container();
})
),
),
)],
),
],
),
),
);
}
}

Why does ontap change all cards

I am still new to coding and still learning dart. I can't find a solution anywhere. please help. when I run my code, everything works fine but when i add multiple cards, when i tap one, they all change color and have a strikethrough. I am not sure where the problem is. Please can you help, here is my code:
#override
bool _enabled = true;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('To-Do List'),
centerTitle: true,
backgroundColor: Colors.grey[900],
),
body: ListView(children: _getItems()),
backgroundColor: Colors.grey[850],
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
onPressed: () => _displayDialog(context),
tooltip: 'Add Item',
child: Icon(Icons.add),
backgroundColor: Colors.grey[900],
),
),
);
}
void _addTodoItem(String title) {
//Wrapping it inside a set state will notify
// the app that the state has changed
setState(() {
_todoList.add(title);
});
_textFieldController.clear();
}
final Map<String, bool> _enabledMap = Map<String, bool>();
Widget _buildTodoItem(String title) {
return Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: InkWell(
onTap: () => setState(() {
item.isTapped = !item.isTapped;
// _enabled = !_enabled;
// _color = Colors.grey;
}),
child: Container(
child: Container(
width: 50,
height: 75,
alignment: Alignment.center,
child: Text(
title,
style: TextStyle(decoration: _enabledMap[title] == true ? TextDecoration.lineThrough, color : null: Colors.grey[700]),
),
color: _color,
),
),
)
);
}
//Generate a single item widget
_displayDialog(BuildContext context) async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Add a task to your List'),
content: TextField(
controller: _textFieldController,
decoration: const InputDecoration(hintText: 'Enter task here'),
),
actions: <Widget>[
FlatButton(
child: const Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: const Text('ADD'),
onPressed: () {
Navigator.of(context).pop();
_addTodoItem(_textFieldController.text);
},
),
],
);
});
}
Your onTap method updates the _enabled variable in setState.
That variable is used for all the containers in their TextStyle widget.
In order to select one item, I suggest creating a map that'll store your "enabled" logic, and the key should be a unique String (the title).
Something like below: (not tested)
final Map<String, bool> _enabledMap = Map<String, bool>();
enter code here
Widget _buildTodoItem(String title) {
return Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: InkWell(
onTap: () => setState(() { if (_enabledMap[title] == null) {_enabledMap[title] = false;} _enabledMap[title] = !_enabledMap[title]; _color = Colors.grey;}),
child: Container(
width: 50,
height: 75,
alignment: Alignment.center,
child: Text(
title,
style: TextStyle(decoration: _enabledMap[title] == true ? TextDecoration.lineThrough, color: Colors.grey[700] : null),
),
color: _color,
),
),
)
);
class Details {
String title;
bool isTapped;
Details({this.title, this.isTapped});
}
class Testing2 extends StatefulWidget {
#override
_Testing2State createState() => _Testing2State();
}
class _Testing2State extends State<Testing2> {
#override
bool _enabled = true;
List<Details> _todoList = [];
List<Widget> lists = [];
TextEditingController _textFieldController = TextEditingController();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('To-Do List'),
centerTitle: true,
backgroundColor: Colors.grey[900],
),
body: _getItems(), //ListView(children: _getItems()),
backgroundColor: Colors.grey[850],
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
onPressed: () => _displayDialog(context),
tooltip: 'Add Item',
child: Icon(Icons.add),
backgroundColor: Colors.grey[900],
),
),
);
}
Widget _getItems() {
return Container(
child:_todoList.length>0? ListView.builder(
itemCount: _todoList.length,
itemBuilder: (context, index) {
return _buildTodoItem(_todoList[index]);
})
:Center(child: Text("It's Empty", style: TextStyle(color: Colors.white),),),
);
}
void _addTodoItem(String title) {
setState(() {
_todoList.add(Details(isTapped: false, title: title));
});
_textFieldController.clear();
}
Widget _buildTodoItem(Details item) {
return Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: InkWell(
onTap: () => setState(() {
item.isTapped = !item.isTapped;
}),
child: Container(
width: 50,
height: 75,
alignment: Alignment.center,
child: Text(
item.title,
style: TextStyle(
decoration:
item.isTapped ? null : TextDecoration.lineThrough,
color: Colors.grey[700]),
),
color: item.isTapped ? Colors.grey : null,
// _color
),
)));
}
//Generate a single item widget
_displayDialog(BuildContext context) async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Add a task to your List'),
content: TextField(
controller: _textFieldController,
decoration: const InputDecoration(hintText: 'Enter task here'),
),
actions: <Widget>[
FlatButton(
child: const Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: const Text('ADD'),
onPressed: () {
Navigator.of(context).pop();
_addTodoItem(_textFieldController.text);
},
),
],
);
});
}
}

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

Scroll View Not Responding in flutter

My Scrollview not Responding, can someone tell what I am missing in code:
Please Suggest me how to add scroll view listener I'm beginner.
import 'package:flutter/material.dart';
import 'package:share/share.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import '../main.dart';
import 'favourite_articles.dart';
import 'coin_system.dart';
class Settings extends StatefulWidget {
#override
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
bool _notification = false;
ScrollController _controller;
#override
void initState() {
super.initState();
checkNotificationSetting();
}
checkNotificationSetting() async {
final prefs = await SharedPreferences.getInstance();
final key = 'notification';
final value = prefs.getInt(key) ?? 0;
if (value == 0) {
setState(() {
_notification = false;
});
} else {
setState(() {
_notification = true;
});
}
}
saveNotificationSetting(bool val) async {
final prefs = await SharedPreferences.getInstance();
final key = 'notification';
final value = val ? 1 : 0;
prefs.setInt(key, value);
if (value == 1) {
setState(() {
_notification = true;
});
} else {
setState(() {
_notification = false;
});
}
Future.delayed(const Duration(milliseconds: 500), () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (BuildContext context) => MyHomePage()));
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: true,
title: Text(
'More',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 20,
fontFamily: 'Poppins'),
),
elevation: 5,
backgroundColor: Colors.white,
actions: <Widget>[
IconButton(
icon: Icon(Icons.mail),
color: Colors.black,
tooltip: 'Song Request',
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CoinSystem(),
),
);
})
],
),
body: Container(
decoration: BoxDecoration(color: Colors.white),
child: SingleChildScrollView(
controller: _controller,
scrollDirection: Axis.vertical,
child: Column(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 20, 0, 10),
child: Image(
image: AssetImage('assets/icon.png'),
height: 50,
),
),
Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 20),
child: Text(
"Version 2.1.0 \n ",
textAlign: TextAlign.center,
style: TextStyle(height: 1.6, color: Colors.black87),
),
),
Divider(
height: 10,
thickness: 2,
),
//ListWheelScrollView(
ListView(
//itemExtent: 75,
shrinkWrap: true,
children: <Widget>[
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FavouriteArticles(),
),
);
},
child: ListTile(
leading: Image.asset(
"assets/more/favourite.png",
width: 30,
),
title: Text('Favourite'),
subtitle: Text("See the saved songs"),
),
),
//Song Request Code
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CoinSystem(),
),
);
},
child: ListTile(
leading: Image.asset(
"assets/more/songrequest.png",
width: 30,
),
title: Text('Songs Request'),
subtitle: Text("Request your favourite songs"),
),
),
//Song Request Code End
ListTile(
leading: Image.asset(
"assets/more/notification.png",
width: 30,
),
isThreeLine: true,
title: Text('Notification'),
subtitle: Text("Change notification preference"),
trailing: Switch(
onChanged: (val) async {
await saveNotificationSetting(val);
},
value: _notification),
),
],
)
],
),
),
),
//),
);
//);
}
}
So, I have tried SingleChildScrollView, in that I have Container and Listview. But Listview doesn't response on scrolling action in landscape mode.
I have added ScrollController _controller; Do i have to create _controller class that listern the scrolling action?
In my understanding, you want to be able to get 2 scrolling. 1. using SingleChildScrollView and inside that Widget, you want to be able to scroll the bottom layer, thus you use ListView. To make it work, you have to place your ListView inside widget that has certain height. Example this implementation is:
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: <Widget>[
SizedBox(child: Text('Upper scrollable'), height: 450),
Divider(
height: 10,
thickness: 2,
),
Container(
height: 350,
child: ListView(
shrinkWrap: true,
children: <Widget>[
Container(
color:Colors.red,
child: SizedBox(child: Text('Bottom scrollable'), height: 450),
),
],
),
)
],
),
),
If you don't want to use 2 scroll, don't use ListView inside SingleChildScrollView.
ListView cannot be wrapped with SingleChildScrollView remove it
surround ListView with Expanded Widget
try one of the two alternatives.

Flutter/Dart how to pick a date and populate text field with selection

I am trying to let users add dates to a list in my app and I have managed to create my text field as well as the date selector. I am struggling to set the value of the selected date to a variable and populate the text field when a user picks one. I have tried accessing the _date value from _selectDate but still nothing populates my TextField.
Here is my code:
class DatesToRemember extends StatefulWidget {
#override
_DatesToRememberState createState() => _DatesToRememberState();
}
class _DatesToRememberState extends State<DatesToRemember> {
DateTime selectedDate = DateTime.now();
TextEditingController _date = new TextEditingController();
Future<Null> _selectDate(BuildContext context) async {
DateFormat formatter =
DateFormat('dd/MM/yyyy'); //specifies day/month/year format
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(1901, 1),
builder: (BuildContext context, Widget child) {
return Theme(
data: ThemeData.light().copyWith(
colorScheme: ColorScheme.light(
primary: kPrimaryColor,
onPrimary: Colors.black,
),
buttonTheme: ButtonThemeData(
colorScheme: Theme.of(context)
.colorScheme
.copyWith(primary: Colors.black),
),
),
child: child,
);
},
lastDate: DateTime(2100));
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
_date.value = TextEditingValue(
text: formatter.format(
picked));//Use formatter to format selected date and assign to text field
});
return _date;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: GestureDetector(
onTap: () => Navigator.pop(context),
child: Icon(Icons.arrow_back)),
title: Text('Dates to Remember'),
),
backgroundColor: Colors.white,
body: Center(
child: Column(children: [
SizedBox(
height: 10.0,
),
Container(
width: MediaQuery.of(context).size.width * 0.8,
child: Text(
"It can be difficult to ",
style: TextStyle(fontFamily: FontNameDefault),
),
),
SizedBox(
height: 50.0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.centerRight,
child: FloatingActionButton(
backgroundColor: kPrimaryColor,
child: Icon(Icons.add),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Add occasion'),
content: Container(
height: 150.0,
child: Column(
children: [
TextField(
onChanged: (String value) {
input = value;
},
decoration: InputDecoration(
hintText: 'Occasion Title'
),
),
TextField(
decoration: InputDecoration(
hintText: 'Pick Date'
),
onTap: () => _selectDate(context),
),
FlatButton(
child: Text('Add'),
onPressed: () {
setState(() {
occasions.add(input);
});
Navigator.of(context).pop();
},
),
],
),
),
);
});
}),
),
),
Container(
height: MediaQuery.of(context).size.height * 0.6,
width: MediaQuery.of(context).size.width * 0.9,
decoration: BoxDecoration(
border: Border.all(color: Colors.black26)
),
child:
occasions.isEmpty? Center(child: Text('Add an occasion', style: TextStyle(
color: Colors.black
),)) : ListView.builder(
itemCount: occasions.length,
itemBuilder: (BuildContext context, int index) {
return
Dismissible(
direction: DismissDirection.endToStart,
onDismissed: (direction) {
occasions.removeAt(index);
Scaffold.of(context).showSnackBar(new SnackBar(
content: Text('Occasion Removed'),
duration: Duration(seconds: 5),
));
},
key: UniqueKey(),
child: Card(
elevation: 8.0,
margin: EdgeInsets.all(8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: ListTile(
title: Text(occasions[index]),
trailing: IconButton(
icon: Icon(
Icons.delete,
color: Colors.red,
),
onPressed: () {
setState(() {
occasions.removeAt(index);
Scaffold.of(context).showSnackBar(new SnackBar(
content: Text('Occasion Removed'),
duration: Duration(seconds: 5),
));
});
},
),
),
),
);
}),
)
]),
));
}
}
Can someone help? Thanks
Try my code below:
DateTime valueDate = DateTime.now();
Row(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 0),
child: Text("${valueDate.toLocal()}".split(' ')[0]),
),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Theme.of(context).accentColor,
width: 2.5,
),
)),
width: 270,
),
RaisedButton(
child: Icon(Icons.date_range),
onPressed: () => _selectDate(context),
)
],
);
The function :
Future<Null> _selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(context: context, initialDate: valueDate, firstDate: DateTime(2015, 8), lastDate: DateTime(2101));
if (picked != null && picked != valueDate)
setState(() {
valueDate = picked;
});
}