Problem with List builder repeat the data when adding or removing item in the list - flutter

I'm new to flutter. When I adding new item or removing an item from the list, the list builder does update the list, but the problem is that the list builder also displaying the previous item list and showing new updated item list. So what I want to do is keeping the new updated item list instead of old item list.
class AlarmPage extends StatefulWidget {
final String title;
AlarmPage({Key key, this.title}) : super(key: key);
#override
_AlarmPageState createState() => _AlarmPageState();
}
class _AlarmPageState extends State<AlarmPage> {
String alarmName;
// Test Function
void _addAlarm() {
setState(() {
Navigator.push(
context, MaterialPageRoute(builder: (context) => AddAlarm()));
});
}
#override
void initState() {
super.initState();
Provider.of<AlarmsProvider>(context, listen: false).getLocalStorage();
}
#override
Widget build(BuildContext context) {
List<Widget> allWidgetsAlarms = List<Widget>();
return Consumer<AlarmsProvider>(builder: (context, alarmProviderItem, _) {
List<String> localAlarms = alarmProviderItem.alarms;
if (localAlarms != null) {
localAlarms.forEach((item) {
allWidgetsAlarms.add(
Stack(
children: <Widget>[
InkWell(
child: Container(
color: Color(0xff212121),
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
// Alarm Name & Title
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 2),
)),
child: Row(
children: <Widget>[
Icon(Icons.alarm, color: Colors.yellow),
SizedBox(width: 20.0),
Text('$item',
style: TextStyle(
color: Color(0xffC1C1C1),
fontSize: 15.0,
fontWeight: FontWeight.w900)),
SizedBox(height: 5),
],
),
),
SizedBox(height: 10),
// Alarm Time & Toggle Switch
Container(
child: Row(
children: <Widget>[
Text(
'Time',
style: TextStyle(
fontSize: 30, color: Colors.white),
),
SizedBox(width: 20),
Text(
'AM / PM',
style: TextStyle(
fontSize: 20, color: Color(0xffB5B5B5)),
),
SizedBox(width: 150),
Icon(Icons.switch_camera, color: Colors.yellow),
],
),
),
// Alarm Repeat
Container(
child: Row(children: <Widget>[
Text(
'Repeat',
style: TextStyle(
fontSize: 11, color: Color(0xff616161)),
),
Container(
child: DaySelector(
value: null,
onChange: (value) {},
color: Colors.yellow[400],
mode: DaySelector.modeFull,
),
),
]),
),
],
),
),
onLongPress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddAlarm(item: item)));
},
),
SizedBox(height: 180),
],
),
);
print(item);
});
}
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text('Azy Alarm'),
centerTitle: true,
),
body: Container(
decoration: BoxDecoration(
image: const DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/images/background_image(dark).png')),
),
// child: ListView(children: allWidgetsAlarms),
child: ListView.builder(
itemCount: allWidgetsAlarms.length,
padding: const EdgeInsets.all(8.0),
itemBuilder: (BuildContext context, int index) {
return allWidgetsAlarms[index];
}),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.blue,
elevation: 0,
onPressed: _addAlarm,
),
);
});
}
}

So I think your issue is this line: allWidgetsAlarms.add( You construct allWidgetsAlarms in your builder, but the builder is not called again every time you Consumer rebuilds, hence it is just appending the new contents to the end of the list. To fix this, keep your original initialization of allWidgetsAlarms just at the top of the builder in your Consumer, add the following line:
allWidgetsAlarms = List<Widget>();
This will resert allWidgetsAlarms. Hope it helps!

Related

Error: Could not find the correct Provider<CartModel> above this Consumer<CartModel> Widget

I got this error while running the app. I not so advanced in flutter yet. Trying to find solutions. Can u guys help me please?
Error: Could not find the correct Provider above this Consumer Widget
This happens because you used a BuildContext that does not include the provider
of your choice. There are a few common scenarios:
You added a new provider in your main.dart and performed a hot-reload.
To fix, perform a hot-restart.
The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
You used a BuildContext that is an ancestor of the provider you are trying to read.
Make sure that Consumer is under your MultiProvider/Provider.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>().toString()),
);
}
consider using builder like so:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context, child) {
// No longer throws
return Text(context.watch<Example>().toString());
}
);
}
My code here below
import 'package:flutter/material.dart';
class CartModel extends ChangeNotifier {
// list of items on sale
final List _shopItems = const [
// [ itemName, itemPrice, imagePath, color ]
["Avocado", "4.00", "lib/images/avocado.png", Colors.green],
["Banana", "2.50", "lib/images/banana.png", Colors.yellow],
["Chicken", "12.80", "lib/images/chicken.png", Colors.brown],
["Water", "1.00", "lib/images/water.png", Colors.blue],
];
// list of cart items
final List _cartItems = [];
get cartItems => _cartItems;
get shopItems => _shopItems;
// add item to cart
void addItemToCart(int index) {
_cartItems.add(_shopItems[index]);
notifyListeners();
}
// remove item from cart
void removeItemFromCart(int index) {
_cartItems.removeAt(index);
notifyListeners();
}
// calculate total price
String calculateTotal() {
double totalPrice = 0;
for (int i = 0; i < cartItems.length; i++) {
totalPrice += double.parse(cartItems[i][1]);
}
return totalPrice.toStringAsFixed(2);
}
}
//another page
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'cart_model.dart';
class CartPage extends StatelessWidget {
const CartPage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle:true,
title: const Text("My Cart",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
backgroundColor: Colors.green[600],
elevation: 0,
iconTheme: IconThemeData(
color: Colors.grey[800],
),
),
body: Consumer<CartModel>(
builder: (context, value, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Let's order fresh items for you
// list view of cart
Expanded(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ListView.builder(
itemCount: value.cartItems.length,
padding: const EdgeInsets.all(12),
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(12.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(8)),
child: ListTile(
leading: Image.asset(
value.cartItems[index][2],
height: 36,
),
title: Text(
value.cartItems[index][0],
style: const TextStyle(fontSize: 18),
),
subtitle: Text(
"\$" + value.cartItems[index][1],
style: const TextStyle(fontSize: 12),
),
trailing: IconButton(
icon: const Icon(Icons.cancel),
onPressed: () =>
Provider.of<CartModel>(context, listen: false)
.removeItemFromCart(index),
),
),
),
);
},
),
),
),
// total amount + pay now
Padding(
padding: const EdgeInsets.all(36.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.green,
),
padding: const EdgeInsets.all(24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Total Price',
style: TextStyle(color: Colors.green[200]),
),
const SizedBox(height: 8),
// total price
Text(
'\$${value.calculateTotal()}',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
// pay now
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.green.shade200),
borderRadius: BorderRadius.circular(28),
),
padding: const EdgeInsets.all(12),
child: Row(
children: const [
Text(
'Pay Now',
style: TextStyle(color: Colors.white),
),
Icon(
Icons.arrow_forward_ios,
size: 16,
color: Colors.white,
),
],
),
),
],
),
),
)
],
);
},
),
);
}
}

Flutter -Widget Text, not updating when value change even with SetState

I have created a container. His child is a text.
When I tap on the container/text, it display a modal and a Picker.
Then, the user can select a value. Press the confirm button and my text widget should change to display the value selected by the user.
But in my case, it is not updating the value of the text widget. I have used that in the past and it was working very well. But here it is not and I do not see why. I am on this since 8:00. A little help would be appreciated. Many thanks.
int valuePickerUnitSelected =0;
String unitCount = '';
int unitCountInt;
String goal = "";
List <String> unitForHabits = ['Count', 'Minute(s)','Hour(s)','Gramme(s)', 'Pound(s)'];
class AddingHabitDetails extends StatefulWidget {
const AddingHabitDetails({Key key}) : super(key: key);
#override
_AddingHabitDetailsState createState() => _AddingHabitDetailsState();
}
class _AddingHabitDetailsState extends State<AddingHabitDetails> {
BuildContext get ctx => null;
#override
Widget build(BuildContext context) {
return Scaffold(
//drawer: new MyMenu(), //TODO a remettre
appBar: new AppBar(
title: new Text('Habits'),
),
body: Column(
children: [
titleZone('Name'),
textFieldHabits('Habit name', context),
titleZone('Goals'),
FlatButton(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (unitCount.length < 2 )...[
Container(
width: 65,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue,
),
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(20))),
child:
Center(child: Text(
'Time', style: TextStyle(color: Colors.black,))))
]
else
...[
Container(
width: 65,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue,),
color: Colors.blue,
borderRadius: BorderRadius.all(
Radius.circular(20))),
child: Center(
child: Text(
unitCount, style: TextStyle(color: Colors.black,))))
],
],
),
onPressed: () {
setState(() {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return ShowPickerUnite(unitForHabits);
});
},
);
},
),
//ChipGoalV3(ctx),// ChipGoal(),
textFieldHabits('Goals', context),
titleZone('Frequency'),
textFieldHabits('Frequency', context),
titleZone('Time Range'),
titleZone('Reminder'),
titleZone('Habits Term'),
],
),
);
}
}
//########################################################################
class ShowPickerUnite extends StatefulWidget {
List<String> myListUnit;
ShowPickerUnite(this.myListUnit, {Key key}) : super(key: key);
#override
_ShowPickerUniteState createState() => _ShowPickerUniteState(
myListUnit);
}
class _ShowPickerUniteState extends State<ShowPickerUnite> {
List <String> myListUnit;
_ShowPickerUniteState(this.myListUnit);
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
decoration: BoxDecoration(
color: Color(0xffffffff),
border: Border(
bottom: BorderSide(
color: Color(0xffffffff),
width: 0.0,
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CupertinoButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
padding: const EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 5.0,
),
),
DefaultTextStyle(
style: TextStyle(
fontSize: 16.0,
color: Colors.black,
fontWeight: FontWeight.bold),
child: Text('Select what you want'),
),
// Text('Energy Needed', style: TextStyle(fontSize: 12.0, color: Colors.black),
// ),
CupertinoButton(
child: Text('Confirm'),
onPressed: () {
setState(() {
unitCount = unitForHabits[valuePickerUnitSelected];
print(unitCount);
});
Navigator.of(context).pop();
},
padding: const EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 5.0,
),
),
],
),
),
Container(
//width: 360,
height: 200,
decoration:BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15.0)),
),
child: CupertinoPicker(
backgroundColor: Colors.white ,
useMagnifier: true,
magnification: 1.3,
scrollController: FixedExtentScrollController(initialItem: 0),
itemExtent: 25,
children: [
for (String name in myListUnit)
Center(
child:Text(name)),
],
onSelectedItemChanged: (value) {
setState(() {
valuePickerUnitSelected = value;
// taskEnergy = myListEnergy[valuePickerEnergySelected];
// taskNewValue ['task_Energy'] = taskEnergy;
});
}))
]);
}
}
Widget inputNameHabit (){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text ('Name Habits',style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold),),
);
}
Widget titleZone (String _titleName){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Text ( _titleName,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold),),
],
),
);
}
Widget textFieldHabits (String item,context){
return TextField(
decoration: InputDecoration(
hintText: item,
filled: true,
fillColor: Colors.grey[300],
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(50)
),
),
onTap: (){
Navigator.push(context,
MaterialPageRoute(
builder: (context) => HabitGoalUnitSelection(), //TODO MODIFIER route selon source
),
);
},);
}
Wait for the dialog to finish and then call setState to update the UI.
Modify this way
onPressed: () async {
await showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return ShowPickerUnite(unitForHabits);
});
setState(() {});

Flutter : Is there a way to make a gridview wait until I load all the data

I am reading from the local DB (SqlLite) and my gridview doesn't render when I press restart. However, when I do a hot reload the grid renders just fine with the data. I am guessing during the init since the data is still being loaded and the gridview doesn't wait. Is there any way I can manage that?
Here is my code.
class BookShelfList extends StatefulWidget {
const BookShelfList({Key? key}) : super(key: key);
#override
State<BookShelfList> createState() => _BookShelfListState();
}
class _BookShelfListState extends State<BookShelfList> {
late List<BookShelf> data = [];
#override
void initState() {
// TODO: implement initState
super.initState();
_getBooks();
}
#override
Widget build(BuildContext context) {
return Container(
height: 300,
child: Column(
children: [
Text("You have ${data.length} books "),
Flexible(child: buildGridList(data)),
],
),
);
}
Widget buildGridList(List<BookShelf> data) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
),
itemCount: data.length,
itemBuilder: (BuildContext context, index) {
return Card(
margin: EdgeInsets.all(5),
child: GridTile(
header: GridTileBar(
backgroundColor: Colors.white,
title: Text(
data[index].author,
style: TextStyle(color: Colors.black),
),
subtitle: Text(data[index].dateAdded,
style: TextStyle(color: Colors.grey)),
trailing: IconButton(
onPressed: () {},
icon: const Icon(
Icons.more_vert_rounded,
color: Colors.black54,
)),
),
child: Image.network(
data[index].thumbnail,
height: 60,
width: 70,
fit: BoxFit.fill,
),
footer: GridTileBar(
backgroundColor: Colors.white,
title: Row(
children: const [
Icon(
Icons.favorite_outline,
color: Colors.grey,
),
Text('20', style: TextStyle(color: Colors.black)),
SizedBox(
width: 20,
),
Icon(
Icons.chat_bubble_outline,
color: Colors.grey,
),
Text(
'5',
style: TextStyle(color: Colors.black),
),
],
),
trailing: const Icon(
Icons.bookmark_outline,
color: Colors.black,
),
)),
);
},
);
_getBooks() async {
data = await BookShelfDbProvider().fetchBook();
}}
Try calling setState() in _getBooks() right after the data = await BookShelfDbProvider().fetchBook();
Make Gridview.builder a child of future builder and pass future to _getBooks()
What happens is, while the _getBooks() function is running, you could show a CircularProgressBar, and as soon as the data is received, GridView.builderis triggered.
And calling _getBooks() in initState() is not necessary in this case.
Here's your updated code:
_getBooks() async {
data = await BookShelfDbProvider().fetchBook();
}
class BookShelfList extends StatefulWidget {
const BookShelfList({Key? key}) : super(key: key);
#override
State<BookShelfList> createState() => _BookShelfListState();
}
class _BookShelfListState extends State<BookShelfList> {
late List<BookShelf> data = [];
#override
Widget build(BuildContext context) {
return Container(
height: 300,
child: Column(
children: [
Text("You have ${data.length} books "),
Flexible(child: buildGridList(data)),
],
),
);
}
Widget buildGridList(List<BookShelf> data) {
return FutureBuilder(
future: _getBooks(),
builder: (context, snapshot){
if(snapshot!=null){
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
),
itemCount: data.length,
itemBuilder: (BuildContext context, index) {
return Card(
margin: EdgeInsets.all(5),
child: GridTile(
header: GridTileBar(
backgroundColor: Colors.white,
title: Text(
data[index].author,
style: TextStyle(color: Colors.black),
),
subtitle: Text(data[index].dateAdded,
style: TextStyle(color: Colors.grey)),
trailing: IconButton(
onPressed: () {},
icon: const Icon(
Icons.more_vert_rounded,
color: Colors.black54,
)),
),
child: Image.network(
data[index].thumbnail,
height: 60,
width: 70,
fit: BoxFit.fill,
),
footer: GridTileBar(
backgroundColor: Colors.white,
title: Row(
children: const [
Icon(
Icons.favorite_outline,
color: Colors.grey,
),
Text('20', style: TextStyle(color: Colors.black)),
SizedBox(
width: 20,
),
Icon(
Icons.chat_bubble_outline,
color: Colors.grey,
),
Text(
'5',
style: TextStyle(color: Colors.black),
),
],
),
trailing: const Icon(
Icons.bookmark_outline,
color: Colors.black,
),
)),
);
},
);
} else {
return CircularProgressIndicator();
}
}
);
Please adjust the {}'s as necessary.

Why does Late Initialization Error occur?

The application has the function of adding news to favorites. But when I go to the Favorites page, I get the error "Late Initialization Error: Field "article" has not been initialized.
The problem is in the button "Details", in the line:
MaterialPageRoute(builder: (context) => ArticlePage(article: article,))
Please help me solve the problem. Below is the code for this page:
class FavScreen extends StatefulWidget {
const FavScreen({Key? key}) : super(key: key);
#override
State<FavScreen> createState() => _FavScreenState();
}
class _FavScreenState extends State<FavScreen> {
late final Article article;
final _fireStore = FirebaseFirestore.instance.collection('favoriteItems');
#override
void initState() {
article = Article(
author: article.author,
title: article.title,
description: article.description,
url: article.url,
urlToImage: article.urlToImage,
publishedAt: article.publishedAt,
content: article.content,
source: article.source,
);
super.initState();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Favorite News', style: TextStyle(color: Colors.white)),
backgroundColor: Color(0xfff27935),
),
body:
StreamBuilder(
stream: _fireStore.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if(!snapshot.hasData) {
return Text('No featured news');
} else {
return ListView.builder(
itemCount: snapshot.data?.docs.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: Container(
margin: EdgeInsets.all(12.0),
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 3.0,
),
]),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 200.0,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(snapshot.data?.docs[index].get('image')), fit: BoxFit.cover),
borderRadius: BorderRadius.circular(12.0),
),
),
SizedBox(
height: 8.0,
),
Container(
child: Row(
textDirection: TextDirection.ltr,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
padding: EdgeInsets.all(6.0),
decoration: BoxDecoration(
color: Color(0xfff27935),
borderRadius: BorderRadius.circular(30.0),
),
child: Text(
snapshot.data?.docs[index].get('name'),
style: TextStyle(
color: Colors.white,
),
),
),
IconButton(
onPressed: () {
_fireStore.doc(snapshot.data?.docs[index].id).delete();
},
icon: const Icon(Icons.bookmark_remove)),
]
)
),
SizedBox(
height: 8.0,
),
Text(
snapshot.data?.docs[index].get('title'),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
SizedBox(
height: 10.0,
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ArticlePage(
article: article,
)));
},
child: new Text("DETAILS", style: TextStyle(
fontSize: 12.0,
),
),
)
],
),
),
);
}
);
}
},
)
);
}
}
article = Article(
author: article.author,
title: article.title,
description: article.description,
url: article.url,
urlToImage: article.urlToImage,
publishedAt: article.publishedAt,
content: article.content,
source: article.source,
);
You're trying to initialize article by creating a new Article with values from article. article is uninitialized however, so it fails to read these values and spits out an error.
I'm not quite sure what you want to achieve, but I guess you want to pass in an Article into the widget and initialize the article variable in your state class with that?

CustomScrollView object does not update with input from StatefulBuilder

I have a CustomScrollView that gets updated upon user input. The actual items in the ListView are in a SliverChildBuilderDelegate inside the CustomScrollView which is inside the body of the Scaffold object (see the code below). If a user adds an item in the form that is inside the StatefulBuilder which is inside a showDialog object, the item does not get added to the planets list which thus does not update the ListView. I think the problem is caused by the StatefulBuilder which I need to update my DropdownButton.
My code:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
void main() {
runApp(MaterialApp(
home: HomePage(),
));
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class Planet {
final String id;
final String name;
final String location;
final String distance;
final String gravity;
final String image;
const Planet({this.id, this.name, this.location, this.distance, this.gravity, this.image});
}
class Coin {
int id;
String name;
Coin(this.id, this.name);
static List<Coin> getCoins() {
return <Coin>[
Coin(1, 'coin1'),
Coin(2, 'coin2'),
Coin(3, 'coin3'),
Coin(4, 'coin4'),
Coin(5, 'coin5'),
];
}
}
class MenuItem {
String title;
String icon;
Color color;
Function func;
MenuItem(this.title, this.icon, this.color, this.func);
}
class _HomePageState extends State<HomePage> {
List<Coin> _coins = Coin.getCoins();
List<DropdownMenuItem<Coin>> _dropdownMenuItems;
Coin _selectedCoin;
#override
void initState() {
_dropdownMenuItems = buildDropdownMenuItems(_coins);
_selectedCoin = _dropdownMenuItems[0].value;
super.initState();
_menuItems = createMenuItems();
_selectedMenuItem = _menuItems.first;
}
MenuItem _selectedMenuItem;
List<MenuItem> _menuItems;
List<Widget> _menuOptionWidgets = [];
List<MenuItem> createMenuItems() {
final menuItems = [
new MenuItem("Dashboard", 'assets/images/dashboard.png', Colors.black, () => new Dashboard()),
new MenuItem("Cows", 'assets/images/cow.png', Colors.green, () => new Cows()),
];
return menuItems;
}
_onSelectItem(MenuItem menuItem) {
setState(() {
_selectedMenuItem = menuItem;
});
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
Navigator.of(context).pop(); // close side menu
}
List<DropdownMenuItem<Coin>> buildDropdownMenuItems(List coins) {
List<DropdownMenuItem<Coin>> items = List();
for (Coin coin in coins) {
items.add(
DropdownMenuItem(
value: coin,
child:
Text(
coin.name,
style: TextStyle(
fontSize: 18.0,
color: Colors.black87,
fontWeight: FontWeight.bold
),
),
),
);
}
return items;
}
onChangeDropdownItem(Coin selectedCoin, StateSetter setState) {
setState(() {
_selectedCoin = selectedCoin;
print('${_selectedCoin.name}');
});
}
final coinController = TextEditingController();
final amountController = TextEditingController();
final purposeController = TextEditingController();
#override
void dispose() {
// Clean up the controller when the widget is disposed.
coinController.dispose();
amountController.dispose();
purposeController.dispose();
super.dispose();
}
List<Planet> planets = [];
#override
Widget build(BuildContext context) {
_menuOptionWidgets = [];
DateTime now = DateTime.now();
String formattedDate = DateFormat('yyyy-MM-dd kk:mm').format(now);
for (var menuItem in _menuItems) {
_menuOptionWidgets.add(new Container(
decoration: new BoxDecoration(
color: menuItem == _selectedMenuItem
? Colors.grey[200]
: Colors.white),
child: new ListTile(
leading: new Image.asset(menuItem.icon),
onTap: () => _onSelectItem(menuItem),
title: Text(
menuItem.title,
style: new TextStyle(
fontSize: 20.0,
color: menuItem.color,
fontWeight: menuItem == _selectedMenuItem
? FontWeight.bold
: FontWeight.w300),
))));
_menuOptionWidgets.add(
new SizedBox(
child: new Center(
child: new Container(
margin: new EdgeInsetsDirectional.only(start: 20.0, end: 20.0),
height: 0.3,
color: Colors.grey,
),
),
),
);
}
double screenHeight;
screenHeight = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
title: Text('Dashboard'),
backgroundColor: Color.fromRGBO(53, 73, 94, 0.9),
elevation: 0.0,
// leading: Container(),
),
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new Container(
child: new ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.black,
radius: 40.0,
child: Text(
"L",style: TextStyle(
color: Colors.orange,
fontSize: 46.0),
),
),
title: Text("Welcome",style: TextStyle(fontSize: 46.0),)
),
margin: new EdgeInsetsDirectional.only(top: 20.0),
color: Colors.white,
constraints: BoxConstraints(maxHeight: 90.0, minHeight: 90.0)),
new SizedBox(
child: new Center(
child: new Container(
margin:
new EdgeInsetsDirectional.only(start: 10.0, end: 10.0),
height: 0.3,
color: Colors.black,
),
),
),
new Container(
color: Colors.white,
child: new Column(children: _menuOptionWidgets),
),
],
),
),
floatingActionButton: new Container(
width: 120.0,
height: 120.0,
padding: const EdgeInsets.only(bottom:40.0),
child: FloatingActionButton(
child: Icon(Icons.add,size: 50.0),
elevation: 0.0,
onPressed: () {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
margin: EdgeInsets.only(
top: screenHeight / 5,
bottom: screenHeight / 4
),
padding: EdgeInsets.only(left: 10, right: 10),
child: Card(
color: Color.fromRGBO(53, 73, 94, 0.9),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 8,
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Text(
"Create",
style: Style.headerTextStyle
),
),
Divider(
color: Colors.white
),
SizedBox(
height: 15,
),
DropdownButton(
value: _selectedCoin,
items: _dropdownMenuItems,
onChanged: (selectedCoin) {
setState(() {
_selectedCoin = selectedCoin;
print('${_selectedCoin.name}');
});
}, //onChangeDropdownItem(_selectedCoin, setState),
),
SizedBox(
height: 15,
),
TextFormField(
decoration: InputDecoration(
labelText: "Amount",
hasFloatingPlaceholder: true,
labelStyle: Style.commonTextStyle
),
controller: amountController,
),
SizedBox(
height: 20,
),
TextFormField(
decoration: InputDecoration(
labelText: "What is it for?",
hasFloatingPlaceholder: true,
labelStyle: Style.commonTextStyle
),
controller: purposeController,
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment
.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(),
),
ButtonTheme(
minWidth: 150.0,
child: RaisedButton(
padding: EdgeInsets.all(8.0),
child: Text('Share',
style: TextStyle(
fontSize: 24,
color: Colors.black87,
fontWeight: FontWeight.bold
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
18.0)
),
color: Colors.white,
splashColor: Colors.blueGrey,
onPressed: () {
setState(() {
planets.add(Planet(
id: '1',
// TODO need to adjust this
name: purposeController.text,
location: '€' + amountController.text,
distance: formattedDate,
gravity: 'test',
image: _setImage(), // TODO might have to pass _selectedCoin as parameter
)
);
});
Navigator.pop(context);
},
),
),
],
),
],
),
),
),
);
}
);
},
);
},
),
),
body: Column(
children: <Widget>[
new Expanded(
child: new Container(
color: Color.fromRGBO(53, 73, 94, 0.9),
child: new CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[
new SliverPadding(
padding: const EdgeInsets.symmetric(vertical: 0.0),
sliver: new SliverFixedExtentList(
itemExtent: 152.0,
delegate: new SliverChildBuilderDelegate(
(context, index) => new PlanetRow(planets[index]),
childCount: planets.length,
),
),
),
],
),
),
),
],
),
);
}
}
The expected result is that the object from user input gets added to the planets list. The Sliver object then gets the updated planets list which shows the user input in a Planet Card. Any help will be greatly appreciated!