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

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();
})
),
),
)],
),
],
),
),
);
}
}

Related

Flutter|Updating a ListView

everyone!
I have a HomeScreen, with this code:
return SafeArea(
child: Scaffold(
body: Stack(
children: [
Padding(
padding: const EdgeInsets.only(left: 8, right: 8),
child: Column(children: [
ActiveTaskInfo(
task: tasks.first,
),
const TextWidget(),
Expanded(child: TasksList()),
const SizedBox(height: 80),
]),
),
BottomBarClass(),
],
),
),
);
TasksList() - ListView.
BottomBarClass() - It is a container with a button inside.
If you return the code itself to the main HomeScreen file, everything works, but if you put it in a separate class and when you add a new item to the list (through the button) nothing happens, but if you press Hot Reload, then the new item in the list is displayed.
Code BottomBarClass():
Positioned(
bottom: 0, left: 0,
child: ClipRRect(
borderRadius: const BorderRadius.only(topRight: Radius.circular(30), topLeft: Radius.circular(30)),
child: Container(
height: 80, width: MediaQuery.of(context).size.width,
color: const Color(0xff070417),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(Icons.watch_later, color: Colors.white.withOpacity(0.4)),
IconButton(icon: Icon(Icons.add, color: Colors.white.withOpacity(0.4),), iconSize: 32, onPressed: () async {
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
return TaskAdding();
}));
if (result == true) {
setState(() {
});
}
}),
Icon(Icons.pie_chart_rounded, color: Colors.white.withOpacity(0.4), size: 24,),
],),
),
));
Вот пример GIF: https://gifyu.com/image/Spp1O
TaskAdding():
import 'package:flutter/material.dart';
import '../expansions/task_tags_decorations.dart';
import '../expansions/tasks_data.dart';
class TaskAdding extends StatefulWidget {
const TaskAdding({Key? key}) : super(key: key);
#override
State<TaskAdding> createState() => _TaskAddingState();
}
class _TaskAddingState extends State<TaskAdding> {
late String _addField;
late Widget _selectedValue;
late bool _active;
late int _selectedIndex;
#override
void initState() {
_addField = 'Empty';
_active = false;
_selectedValue = tasks[0].icon;
_selectedIndex = 0;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Add'), backgroundColor: Colors.pink),
body: Column(children: [
Text('Add Task', style: TextStyle(color: Colors.white, fontSize: 24),),
TextField(onChanged: (String value) {
_addField = value;
}),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DropdownButton<Widget>(
value: _selectedValue,
onChanged: (newValue) {
setState(() {
_selectedValue = newValue!;
});
},
items: dropdownItems,
),
ElevatedButton(
onPressed: () {
setState(() {
tasks.addAll({
TaskData(
taskName: _addField,
tagOne: _active
? tasks[0].tagOne
: tasks[1].tagOne,
tagTwo: tagTwoContainer[_selectedIndex],
icon: _selectedValue,
taskTime: '00:32:10',
)
});
decorations.addAll({
TaskTagsDecorations(
iconColor: const Color(0xff7012CF))
});
});
Navigator.of(context).pop(true);
},
child: const Text('Add')),
],
),
Center(
child: ListTile(
title: _active
? Center(
child: tasks[0].tagOne,
)
: Center(child: tasks[1].tagOne),
selected: _active,
onTap: () {
setState(() {
_active = !_active;
});
},
),
),
SizedBox(
height: 52,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: tagTwoContainer.length,
itemBuilder: (context, index) {
var tagTwoList = tasks[index].tagTwo;
return SizedBox(
height: MediaQuery.of(context).size.height, width: 160,
child: ListTile(
visualDensity: VisualDensity.compact,
selected: index == _selectedIndex,
selectedTileColor: Colors.indigo.withOpacity(0.6),
title: Align(
alignment: Alignment.topCenter,
child: tagTwoList),
onTap: () {
setState(() {
_selectedIndex = index;
});
},
),
);
}),
),
],),
);
}
List<DropdownMenuItem<Widget>> get dropdownItems {
List<DropdownMenuItem<Widget>> menuItems = [
DropdownMenuItem(
child: const Icon(Icons.free_breakfast),
value: iconCircle[0],
),
DropdownMenuItem(
child: const Icon(Icons.grade_outlined), value: iconCircle[1]),
DropdownMenuItem(child: const Icon(Icons.gamepad), value: iconCircle[2]),
DropdownMenuItem(
child: const Icon(Icons.face_rounded), value: iconCircle[3]),
];
return menuItems;
}
}
You question is not clear. Try to add TasksList()
My solution:
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return HomeScreen();
}));

Using TabBar like filter

i'm trying to make a Tabbar that appear in a new page when the search icon in pressed. The code works fine but i don't know how to implement this tabbar. I want to use the tabbar for splitting the search info, each icon has to show only specific info.
I guess each icon has a specific list?
This is my search_tool.dart this appear when the icon button at the main page is pressed
[EDIT] Now the result is shown correctly, but when I press the search box to write the error message contained in buildSuggestion always appears, instead it should only show the list with the relative records and if something not belonging to that category is searched then it must give the error message
import 'package:flutter/material.dart';
import 'package:solaris/lista_data.dart';
import 'constants.dart';
class LinkItemsSearch extends SearchDelegate<LinkItem>{
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
#override
List<Widget> buildActions(BuildContext context) {
return [IconButton(icon: Icon(Icons.clear),onPressed: () { query=""; },)];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back),);
}
#override
Widget buildResults(BuildContext context) {
var mylist = loadLinkItem().where((p) => p.description.contains(query)).toList();
return Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
final mylist = query.isEmpty? loadLinkItem():loadLinkItem().where((p) => p.description.contains(RegExp(query, caseSensitive: false))).toList();
return mylist.isEmpty?
Container(
color: red,
child: Center(child: Text('No Result Found . . .', style: TextStyle(color: Colors.white,fontSize: 20,))),
):Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(onTap: (){ showResults(context);},
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
}
Search icon
IconButton(onPressed:(){
showSearch(context: context, delegate: LinkItemsSearch());
}, icon: Icon(Icons.search),),
List
class LinkItem{
final String title;
final String description;
final link;
LinkItem({
required this.title,
required this.description,
required this.link,
});
}
List<LinkItem> loadLinkItem(){
var link = <LinkItem>[
LinkItem(
title: 'Title1',
description: 'Apps',
link: Title1(),
),LinkItem(
title: 'Title2',
description: 'Movies',
link: Title2(),
),LinkItem(
title: 'Title3',
description: 'Games',
link: Title3(),
),
];
return link;
}
You can override the buildBottom method in your LinkItemsSearch:
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
For this to work, you have to create myList on the top of your LinkItemsSearch and reuse it when filtering everywhere.
Also, I just updated loadLinkItem method to have some input for filtering:
List<LinkItem> loadLinkItem() {
var link = <LinkItem>[
LinkItem(
title: 'Title1',
description: 'Movies',
link: '',
),
LinkItem(
title: 'Title2',
description: 'Games',
link: '',
),
LinkItem(
title: 'Title3',
description: 'Apps',
link: '',
),
];
return link;
}
Of course, I have not completely matched your style, so I did not style buttons as you need it, you might higher bottom bar than 60 as I used. I also have not attached any on press handlers since I am not sure what should they do, but it looks as it is expected: https://i.stack.imgur.com/osUkt.png
I wrapped them with a Column and SingleChildScrollView in case you have more of those items and they need to be scrollable: https://i.stack.imgur.com/FyWVX.png
You can even add some conditions in cases when you don't need this bottom bar to be displayed and in that case, you can just return null from the buildBottom method.
FIX
import 'package:flutter/material.dart';
import 'package:solaris/lista_data.dart';
import 'constants.dart';
class LinkItemsSearch extends SearchDelegate<LinkItem>{
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
#override
List<Widget> buildActions(BuildContext context) {
return [IconButton(icon: Icon(Icons.clear),onPressed: () { query=""; },)];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back),);
}
#override
Widget buildResults(BuildContext context) {
var mylist = loadLinkItem().where((p) => p.description.contains(query)).toList();
return Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
final mylist = query.isEmpty? loadLinkItem():loadLinkItem().where((p) => p.description.contains(RegExp(query, caseSensitive: false))).toList();
return mylist.isEmpty?
Container(
color: red,
child: Center(child: Text('No Result Found . . .', style: TextStyle(color: Colors.white,fontSize: 20,))),
):Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(onTap: (){ showResults(context);},
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
}

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

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.

alertDialog didn't get called onPressed

Hi so I'm trying to show alertDialog when you press the close icon on the card but if I tap the "Close" button, it didn't show the alertDialog for delete confirmation, on the other hand when I tap the "check" Icon on, it successfully show a snackbar.
here's my code for the page:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'Schedule.dart';
class HomeView extends StatefulWidget {
HomeViewState createState() => HomeViewState();
}
class HomeViewState extends State<HomeView> {
final List<Schedule> scheduleList = [
Schedule("Hotel 1", DateTime.now(), DateTime.now(), "Germany"),
Schedule("Hotel 2", DateTime.now(), DateTime.now(), "France")
];
final Icon actionIcon = Icon(Icons.plus_one);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard"),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: actionIcon,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UnscheduledField()),
);
},
)
],
),
body: Container(
child: ListView.builder(
itemCount: scheduleList.length,
itemBuilder: (context, int index) => buildCard(context, index)),
));
}
}
Widget buildCard(BuildContext context, int index) {
final List<Schedule> scheduleList = [
Schedule("Hotel 1", DateTime.now(), DateTime.now(), "Germany"),
Schedule("Hotel 2", DateTime.now(), DateTime.now(), "France")
];
final schedule = scheduleList[index];
return Container(
child: GestureDetector(
onTap: () {
showBottomSheet(
context: context,
builder: (context) => Container(
height: 550,
color: Colors.lightBlue,
));
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 4),
child: Row(
children: <Widget>[
Text(schedule.companyName,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold)),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4, bottom: 4),
child: Row(
children: <Widget>[Text(schedule.location)],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4),
child: Row(
children: <Widget>[
Text('check in at:'),
Text(
"${DateFormat('HH:mm').format(schedule.startTime).toString()}"),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4),
child: Row(children: <Widget>[
Text('check out at:'),
Text(
"${DateFormat('HH:mm').format(schedule.endTime).toString()}"),
]),
),
Row(
children: <Widget>[
Expanded(
child: SizedBox(
height: 40,
child: ListTile(
trailing: IconButton(
onPressed: () {
alert(context);
},
icon: Icon(
Icons.close,
),
color: Colors.red,
),
),
),
),
Expanded(
child: SizedBox(
height: 40,
child: ListTile(
trailing: IconButton(
onPressed: () {
final snackbar = SnackBar(
content: Text('Successfully added'),
duration: Duration(seconds: 2),
);
Scaffold.of(context).showSnackBar(snackbar);
},
icon: Icon(
Icons.check,
),
color: Colors.lightGreen[300],
),
),
),
),
],
),
]))),
));
}
void alert(BuildContext context) {
var alertDialog = AlertDialog(
title: Text("Confirmation"),
content: Text("Are you sure you want to delete this?"),
actions: <Widget>[
FlatButton(
child: Text("No"),
onPressed: () {
Navigator.of(context).pop();
}),
FlatButton(
child: Text("Yes"),
onPressed: () {
Navigator.of(context).pop();
})
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}
Any help would be appreciated! thanks
your code is perfect but you have to define alert dialog before you call it,
So define Alert Dialog before you call it in OnPress method of button and Pass it to alert method
class HomeView extends StatefulWidget {
HomeViewState createState() => HomeViewState();
}
class HomeViewState extends State<HomeView> {
final List<Schedule> scheduleList = [
Schedule("Hotel 1", DateTime.now(), DateTime.now(), "Germany"),
Schedule("Hotel 2", DateTime.now(), DateTime.now(), "France")
];
final Icon actionIcon = Icon(Icons.plus_one);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard"),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: actionIcon,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UnscheduledField()),
);
},
)
],
),
body: buildCard(context, 0),
body: Container(
child: ListView.builder(
itemCount: scheduleList.length,
itemBuilder: (context, int index) => buildCard(context, index)),
)
);
}
}
Widget buildCard(BuildContext context, int index) {
final List<Schedule> scheduleList = [
Schedule("Hotel 1", DateTime.now(), DateTime.now(), "Germany"),
Schedule("Hotel 2", DateTime.now(), DateTime.now(), "France")
];
final schedule = scheduleList[index];
return Container(
child: GestureDetector(
onTap: () {
showBottomSheet(
context: context,
builder: (context) => Container(
height: 550,
color: Colors.lightBlue,
));
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 4),
child: Row(
children: <Widget>[
Text(schedule.companyName,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold)),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4, bottom: 4),
child: Row(
children: <Widget>[Text(schedule.location)],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4),
child: Row(
children: <Widget>[
Text('check in at:'),
Text(
"${DateFormat('HH:mm').format(schedule.startTime).toString()}"),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4),
child: Row(children: <Widget>[
Text('check out at:'),
Text(
"${DateFormat('HH:mm').format(schedule.endTime).toString()}"),
]),
),
Row(
children: <Widget>[
Expanded(
child: SizedBox(
height: 40,
child: ListTile(
trailing: IconButton(
onPressed: () {
var alertDialog = AlertDialog(
title: Text("Confirmation"),
content:
Text("Are you sure you want to delete this?"),
actions: <Widget>[
FlatButton(
child: Text("No"),
onPressed: () {
Navigator.of(context).pop();
}),
FlatButton(
child: Text("Yes"),
onPressed: () {
Navigator.of(context).pop();
})
],
);
alert(context, alertDialog);
},
icon: Icon(
Icons.close,
),
color: Colors.red,
),
title: Text("hello"),
),
),
),
Expanded(
child: SizedBox(
height: 40,
child: ListTile(
trailing: IconButton(
onPressed: () {
final snackbar = SnackBar(
content: Text('Successfully added'),
duration: Duration(seconds: 2),
);
Scaffold.of(context).showSnackBar(snackbar);
},
icon: Icon(
Icons.check,
),
color: Colors.lightGreen[300],
),
),
),
),
],
),
]))),
));
}
void alert(BuildContext context, AlertDialog alertDialog) {
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}

How to navigate to page based on condition in Flutter

I want to navigate to a page based on a condition. When I select 'license' and press the next button it should redirect to license page. When I select 'unlicensed' and press next button it should redirect me to unlicensed page.
After selecting the 'licence'/'unlicensed' value from drop-down it should use that value to determine which page to redirect to.
Here is some code I've tried so far:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
class BspSignupPage extends StatefulWidget {
#override
_BspSignupPageState createState() => _BspSignupPageState();
}
class _BspSignupPageState extends State<BspSignupPage> {
bool bspcheck = false;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _dropdownError;
File _image;
List<String> _colors = <String>[
'',
'Licensed / Register',
'Unregistered',
];
List<DropdownMenuItem<String>> _dropDownItem() {
List<String> ddl = ["License/Registered", "UN-Registered"];
return ddl
.map((value) => DropdownMenuItem(
value: value,
child: Text(value),
))
.toList();
}
Widget _buildbusinesstype() {
String _selectedGender;
return new FormBuilder(
autovalidate: true,
child: FormBuilderCustomField(
attribute: "Business Type",
validators: [
FormBuilderValidators.required(),
],
formField: FormField(
builder: (FormFieldState<dynamic> field) {
return InputDecorator(
decoration: InputDecoration(
prefixIcon: Icon(Icons.merge_type),
errorText: field.errorText),
//isEmpty: _color == '',
child: new DropdownButtonHideUnderline(
child: new DropdownButton(
value: _selectedGender,
items: _dropDownItem(),
onChanged: (value) {
_selectedGender = value;
},
hint: Text('Select Business Type'),
),
),
);
},
),
));
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("BSP Signup"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
),
centerTitle: true,
),
bottomNavigationBar: Container(
color: Colors.transparent,
height: 56,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new FlatButton.icon(
icon: Icon(Icons.close),
label: Text('Clear'),
// color: Colors.redAccent,
textColor: Colors.black,
// padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () {},
),
new FlatButton.icon(
icon: Icon(Icons.ac_unit),
label: Text('Next'),
color: Colors.amber,
textColor: Colors.white,
//padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BspSignupPage()));
}
}),
],
),
),
body: Container(
height: double.infinity,
width: double.infinity,
child: Form(
autovalidate: true,
key: _formKey,
child: Stack(
children: <Widget>[
SingleChildScrollView(
padding: const EdgeInsets.all(30.0),
child: new Container(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildbusinesstype(),
],
),
),
),
],
),
),
),
);
}
}
You can get the value of dropdown using a state variable,
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
class BspSignupPage extends StatefulWidget {
#override
_BspSignupPageState createState() => _BspSignupPageState();
}
class _BspSignupPageState extends State<BspSignupPage> {
bool bspcheck = false;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _dropdownError;
String _dropDownValue = '';
File _image;
List<String> _colors = <String>[
'',
'Licensed / Register',
'Unregistered',
];
List<DropdownMenuItem<String>> _dropDownItem() {
List<String> ddl = ["License/Registered", "UN-Registered"];
return ddl
.map((value) => DropdownMenuItem(
value: value,
child: Text(value),
))
.toList();
}
Widget _buildbusinesstype() {
String _selectedGender;
return new FormBuilder(
autovalidate: true,
child: FormBuilderCustomField(
attribute: "Business Type",
validators: [
FormBuilderValidators.required(),
],
formField: FormField(
builder: (FormFieldState<dynamic> field) {
return InputDecorator(
decoration: InputDecoration(
prefixIcon: Icon(Icons.merge_type),
errorText: field.errorText),
//isEmpty: _color == '',
child: new DropdownButtonHideUnderline(
child: new DropdownButton(
value: _selectedGender,
items: _dropDownItem(),
onChanged: (value) {
_dropDownValue = value;
},
hint: Text('Select Business Type'),
),
),
);
},
),
));
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("BSP Signup"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
),
centerTitle: true,
),
bottomNavigationBar: Container(
color: Colors.transparent,
height: 56,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new FlatButton.icon(
icon: Icon(Icons.close),
label: Text('Clear'),
// color: Colors.redAccent,
textColor: Colors.black,
// padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () {},
),
new FlatButton.icon(
icon: Icon(Icons.ac_unit),
label: Text('Next'),
color: Colors.amber,
textColor: Colors.white,
//padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
// Now use if statement here to decide which route you want to go
if(_dropdDown == "SOME_VALUE"){
// Go to this route
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BspSignupPage()));
}
}),
],
),
),
body: Container(
height: double.infinity,
width: double.infinity,
child: Form(
autovalidate: true,
key: _formKey,
child: Stack(
children: <Widget>[
SingleChildScrollView(
padding: const EdgeInsets.all(30.0),
child: new Container(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildbusinesstype(),
],
),
),
),
],
),
),
),
);
}
}
Unfortunately, I do not have access to Flutter to actually test the code at the moment, but the idea would be as follows.
Keep a state variable that tracks which type of page the app should show. For example, bool license = false. If license is true, navigate to one page. If false, the other. You can code the dropdown list to change that variable.
Once a user has selected one or the other value, use it to navigate to a page based on it. In pseudo code:
FlatButton(
...<styling>...
onPressed: () {
if (_formKey.currentState.validate()) {
if (license) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LicensePage()),
);
} else {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UnlicensedPage()),
);
}
}
}
)