Flutter Firebase realtime database issue - flutter

here is my problem:
database I use has several categories.
Each category has several number of cases.
What I want, is to extract the information from the database, how many cases each category has and to show this information in a list. That means - to show the names of the categories AND how many children (cases) EACH category has (totalCases)...
I read data from database by using feature getNumberOfNodes and so i can get the number of children (cases) of one category by using future builder.
BUT:
If I execute code, I get now the names of all categories and the number of children (cases) which the FIRST category has.
What do I do wrong?
Here is my code, I'm struggling with:
import '../components/category_list_tile.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/material.dart';
import '../constants.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'dart:async';
class ScreenCategoryList extends StatefulWidget {
static String id = 'screen_category_list';
final FirebaseApp app;
ScreenCategoryList({this.app});
#override
_ScreenCategoryListState createState() => _ScreenCategoryListState();
}
class _ScreenCategoryListState extends State<ScreenCategoryList> {
final referenceDatabase = FirebaseDatabase.instance;
//final _dbRef = FirebaseDatabase.instance.reference().child("de");
int counter = 0;
bool showSpinner = false;
DatabaseReference _databaseReference;
#override
void initState() {
final FirebaseDatabase database = FirebaseDatabase(app: widget.app);
_databaseReference = database.reference().child("de");
super.initState();
}
Future<int> getNumberOfNodes(int counter) async {
final response = await FirebaseDatabase.instance
.reference()
.child('de')
.child('category')
.child('$counter')
.child('cases')
.once();
var nodes = [];
response.value.forEach((v) => nodes.add(v));
print(nodes.length);
counter++;
return nodes.length;
}
#override
Widget build(BuildContext context) {
int counter = 0;
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.white, Colors.white],
),
image: const DecorationImage(
image: AssetImage("images/background.png"), fit: BoxFit.cover),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
toolbarHeight: 60.0,
elevation: 0.0,
backgroundColor: Colors.black12,
leading: Padding(
padding: EdgeInsets.only(left: 12.0, top: 12.0, bottom: 12.0),
child: Image(image: AssetImage('images/lexlogo_black.png'))),
title: Center(
child: Column(
children: [
Text(
'Kategorien',
style: TextStyle(
color: kMainDarkColor,
fontFamily: 'Roboto',
fontSize: 21.0,
fontWeight: FontWeight.bold),
),
],
),
),
actions: [
Padding(
padding: EdgeInsets.only(right: 8.0),
child: IconButton(
icon: Icon(Icons.more_vert_rounded),
iconSize: 30.0,
color: kMainDarkColor,
onPressed: () {},
//onPressed: onPressMenuButton,
),
),
],
),
body: FutureBuilder<int>(
future: getNumberOfNodes(counter),
builder: (BuildContext context, AsyncSnapshot<int> casesSnapshot) {
if (casesSnapshot.hasData) {
return FirebaseAnimatedList(
reverse: false,
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
query: _databaseReference.child('category'),
itemBuilder: (
BuildContext context,
DataSnapshot categorySnapshot,
Animation<double> animation,
int index,
) {
int numberOfCases = casesSnapshot.data;
print('$counter, $numberOfCases');
return CategoryListTile(
title: categorySnapshot.value['name'].toString(),
successfulCases: 10,
totalCases: casesSnapshot.data,
onTitleClick: () {},
onInfoButtonClick: () {},
);
},
);
} else if (casesSnapshot.hasError) {
return Center(
child: Column(
children: [
Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${casesSnapshot.error}'),
)
],
),
);
} else {
return Center(
child: Column(
children: [
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
)
],
),
);
}
},
),
),
);
}
}

got it...
here is the code, that worked for me:
class _ScreenCategoryListState extends State<ScreenCategoryList> {
final referenceDatabase = FirebaseDatabase.instance;
bool showSpinner = false;
DatabaseReference _databaseReference;
#override
void initState() {
final FirebaseDatabase database = FirebaseDatabase(app: widget.app);
_databaseReference = database.reference().child("de");
super.initState();
}
Future<Map<int, int>> getNumberOfNodes() async {
Map<int, int> caseNumbers = new Map<int, int>();
// read number of category nodes
final categoriesNumbersResponse = await FirebaseDatabase.instance
.reference()
.child('de')
.child('category')
// .child('0')
// .child('cases')
.once();
var categoryNodes = [];
categoriesNumbersResponse.value.forEach((v) => categoryNodes.add(v));
int numberOfCategories = categoryNodes.length;
//read number of cases in category
for (int i = 0; i < numberOfCategories; i++) {
final caseResponse = await FirebaseDatabase.instance
.reference()
.child('de')
.child('category')
.child('$i')
.child('cases')
.once();
var caseNodes = [];
caseResponse.value.forEach((v) => caseNodes.add(v));
int numberOfCases = caseNodes.length;
caseNumbers[i] = numberOfCases;
}
return caseNumbers;
}
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.white, Colors.white],
),
image: const DecorationImage(
image: AssetImage("images/background.png"), fit: BoxFit.cover),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
toolbarHeight: 60.0,
elevation: 0.0,
backgroundColor: Colors.black12,
leading: Padding(
padding: EdgeInsets.only(left: 12.0, top: 12.0, bottom: 12.0),
child: Image(image: AssetImage('images/lexlogo_black.png'))),
title: Center(
child: Column(
children: [
Text(
'Kategorien',
style: TextStyle(
color: kMainDarkColor,
fontFamily: 'Roboto',
fontSize: 21.0,
fontWeight: FontWeight.bold),
),
],
),
),
actions: [
Padding(
padding: EdgeInsets.only(right: 8.0),
child: IconButton(
icon: Icon(Icons.more_vert_rounded),
iconSize: 30.0,
color: kMainDarkColor,
onPressed: () {},
//onPressed: onPressMenuButton,
),
),
],
),
body: FutureBuilder<Map<int, int>>(
future: getNumberOfNodes(),
builder: (BuildContext context,
AsyncSnapshot<Map<int, int>> casesSnapshot) {
if (casesSnapshot.hasData) {
return FirebaseAnimatedList(
reverse: false,
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
query: _databaseReference.child('category'),
itemBuilder: (
BuildContext context,
DataSnapshot categorySnapshot,
Animation<double> animation,
int index,
) {
int numberOfCases = casesSnapshot.data[index];
//print('number of cases $_counter, $numberOfCases');
return CategoryListTile(
title: categorySnapshot.value['name'].toString(),
successfulCases: 10,
totalCases: numberOfCases,
onTitleClick: () {},
onInfoButtonClick: () {},
);
},
);
} else if (casesSnapshot.hasError) {
return Center(
child: Column(
children: <Widget>[
Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${casesSnapshot.error}'),
)
],
),
);
} else {
return Center(
child: Column(
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
)
],
),
);
}
},
),
),
);
}
}

Related

use variables of one class in another class Flutter

# cartmodel
`class CartModel extends ChangeNotifier {
// list of items on sale
final List _shopItems = const [
// [ itemName, itemPrice, imagePath, color ]
["Avocado", "4", "assets/images/avocado.png", Colors.green],
["Banana", "2", "assets/images/banana.png", Colors.yellow],
["pollo", "12", "assets/images/chicken.png", Colors.brown],
["acqua", "1", "assets/images/water.png", Colors.blue],
["mela", "3", "assets/images/mela.png", Colors.red],
["broccoli", "3", "assets/images/broccoli.png", Colors.brown],
];
final List _faidate = const [
["Avocado", "14000", "assets/images/avocado.png", Colors.orange],
["Banana", "2", "assets/images/banana.png", Colors.blueGrey],
["pollo", "12", "assets/images/chicken.png", Colors.red],
["acqua", "1", "assets/images/water.png", Colors.blue],
];
// list of cart items
final List _cartItems = [];
get faidate => _faidate;
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].toString());
}
return totalPrice.toStringAsFixed(2);
}
}`
cartpage
`class CartPage extends StatelessWidget {
CartPage({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
Device.screenType == ScreenType.tablet;
return Container(
width: 100.w,
height: 90.5.h,
child: Container(
width: 100.w,
height: 20.5.h,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
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
Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Text(
"Cart",
style: GoogleFonts.notoSerif(
fontSize: 36,
fontWeight: FontWeight.bold,
),
),
),
// list view of cart
Expanded(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ListView.builder(
itemCount: (value.cartItems.length),
padding: 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(
'\points ' + 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(25.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.blueGrey[900]),
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(
'\Points ${value.calculateTotal()}',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
// pay now
Container(
),
padding: const EdgeInsets.all(1),
child: Row(
children: [
ElevatedButton(
onPressed: () {},
child: const Text('order now')),
],
),
),
],
),
),
)
],
);
},
),
),
),
);
}
}
`
# points page
`class points extends StatefulWidget {
points({Key? key,}) :super(key: key);
_pointsState createState() => _pointsState();
}
class _pointsState extends State<points> {
int _points = 0;
#override
void initState() {
super.initState();
_loadPunti();
}
_loadPunti() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_points = (prefs.getInt('points') ?? 0);
});
}
_savePunti() async {
await FirebaseFirestore.instance.collection('xxxx').add({
'Points': _points,
});
}
other code...
hi all, I was looking for a solution for this test of a flutter shopping app and I'm having problems in being able to use the "points" variable in the cart page to be able to confirm a purchase on the "onpressed" in the cartpage, I also attached the cartmodel like this to be able to verify. Thank you all

The argument type 'String' can't be assigned to the parameter type 'List<dynamic>'.(flutter)

This is the error:
This is my code:
import 'package:flutter/material.dart';
import 'package:mr_podoro_cleanfile/FrontEnd/pointsAndLevelsShow.dart';
import 'package:mr_podoro_cleanfile/FrontEnd/pomodoro_clock.dart';
import 'package:path_provider/path_provider.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'package:url_launcher/url_launcher.dart';
import '../Backend/Authentication.dart';
import 'PomoDoroAllCounterShow.dart';
import 'aboutMake.dart';
class MainController extends StatefulWidget {
String userName;
Authenticate authenticate;
MainController(this.userName, this.authenticate);
#override
State<StatefulWidget> createState() {
return Functionality(this.userName, this.authenticate);
}
}
class Functionality extends State<MainController> {
String _userName;
int userPoints = 0;
Authenticate authenticate;
Functionality(this._userName, this.authenticate);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xff1dba18),
actions: [
GestureDetector(
onTap: () {
clearCache(context);
},
child: Container(
margin: EdgeInsets.only(
right: 15.0,
),
child: Icon(
Icons.cached_rounded,
size: 25.0,
),
),
),
],
title: Text(
"Pomodoro List",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
),
),
),
drawer: makeDrawer(),
body: mainBody(context),
);
}
Widget makeDrawer() {
return Drawer(
elevation: 20.0,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
heading(),
sideMenu("Account", Icons.account_circle_outlined),
sideMenu("About", Icons.info_outline),
sideMenu("Exit", Icons.exit_to_app_rounded),
],
),
));
}
Widget heading() {
return Container(
color: Color(0xff1dba18),
width: double.infinity,
height: 130.0,
padding: EdgeInsets.only(top: 20.0),
child: Row(
children: [
Expanded(
child: Image.asset(
'assets/images/hi.gif',
fit: BoxFit.fill,
width: 100.0,
)),
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 12.0),
child: Text(
this._userName,
style: TextStyle(
fontSize: 18.0,
color: Colors.white,
),
),
),
),
],
),
);
}
Widget sideMenu(String titleName, IconData takeIcon) {
String command;
if (titleName == "Dashboard") {
command = "DashBoard Pressed";
} else if (titleName == "Account") {
command = "Account Pressed";
} else if (titleName == "Exit") {
command = "Exit Pressed";
} else {
command = "About Pressed";
}
return ListTile(
hoverColor: Colors.deepOrange,
leading: Icon(
takeIcon,
color: Colors.grey,
),
title: Text(
titleName,
style: TextStyle(fontSize: 18.0, color: Colors.black.withOpacity(0.8)),
),
onTap: () async {
if (titleName == "Account") {
List? takeInformation =
await authenticate.fetchDataToPreview(this._userName);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
AccountInformation(this._userName, takeInformation!)));
} else if (titleName == "About") {
const url =
'https://github.com/SamarpanCoder2002/Mr-Promodoro/blob/main/About/aboutThisApp.md';
try {
await launch(
url,
);
} catch (e) {
print("Error in Launch Link");
}
} else {
Navigator.pop(context);
Navigator.pop(context);
}
},
);
}
Widget mainBody(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
const SizedBox(
height: 20,
),
differentPromoDoro(1),
differentPromoDoro(2),
differentPromoDoro(3),
differentPromoDoro(4),
achievement(),
const SizedBox(
height: 20,
),
normalDashboardMake(context),
],
),
);
}
Widget differentPromoDoro([int num = 1]) {
String timeManagement = "";
double wTime, bTime;
if (num == 1) {
timeManagement = "15 min: Working, 3 min: Break";
wTime = 15.0;
bTime = 3.0;
} else if (num == 2) {
timeManagement = "25 min: Working, 5 min: Break";
wTime = 25.0;
bTime = 5.0;
} else if (num == 3) {
timeManagement = "45 min: Working, 15 min: Break";
wTime = 45.0;
bTime = 15.0;
} else {
timeManagement = "90 min: Working, 30 min: Break";
wTime = 90.0;
bTime = 30.0;
}
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
color: Color(0xff1dba18),
elevation: 10.0,
margin: EdgeInsets.only(
bottom: 10.0,
left: 7.0,
right: 7.0,
top: 7.0,
),
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.only(
top: 10.0,
bottom: 10.0,
left: 8.0,
right: 8.0,
),
child: ListTile(
leading: Icon(
Icons.timer_outlined,
color: Colors.white,
size: 30.0,
),
title: Text(
"Pomodoro $num",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w700,
color: Colors.white,
),
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 3),
child: Text(
timeManagement,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w700,
color: Colors.white.withOpacity(0.8),
),
),
),
onTap: () async {
int _userPoints =
await authenticate.getPointsFromDatabase(this._userName);
int _userLevels =
await authenticate.getLevelsFromDatabase(this._userName);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PromoDoroClock(
wTime,
bTime,
_userPoints,
this._userName,
this.authenticate,
_userLevels,
num)));
},
),
),
);
}
Widget achievement() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
achivementStore("point"),
achivementStore("level"),
],
);
}
Widget achivementStore([String? using]) {
Icon iconStore;
String workingStore;
final double sizeFont = 14;
var paddingStore;
if (using == "point") {
iconStore = Icon(Icons.control_point_duplicate_outlined,
size: 20, color: Color(0xff279e23));
workingStore = "Points Earned";
paddingStore = EdgeInsets.only(
top: 3.0,
bottom: 3.0,
);
} else {
iconStore =
Icon(Icons.trending_up_outlined, size: 20, color: Color(0xff279e23));
workingStore = "Levels Achieved";
paddingStore = EdgeInsets.only(
top: 7.0,
bottom: 7.0,
);
}
return Container(
width: 170,
alignment: Alignment.bottomCenter,
margin: EdgeInsets.only(
top: 25.0,
left: 10.0,
right: 10.0,
),
child: TextButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
side: BorderSide(color: Color(0xff279e23)),
borderRadius: BorderRadius.circular(8))),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
iconStore,
const SizedBox(
width: 10,
),
Text(
workingStore,
style: TextStyle(color: Color(0xff279e23), fontSize: sizeFont),
),
],
),
onPressed: () async {
if (using == "point") {
int pointsTake =
await this.authenticate.getPointsFromDatabase(this._userName);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PointsOrValuesShowOnScreen(pointsTake)));
} else {
int levelsTake =
await this.authenticate.getLevelsFromDatabase(this._userName);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PointsOrValuesShowOnScreen(levelsTake, "Levels")));
}
},
),
);
}
Widget normalDashboardMake(BuildContext context) {
return Center(
child: Container(
alignment: Alignment.center,
width: 200.0,
child: TextButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
side: BorderSide(color: Color(0xff279e23)),
borderRadius: BorderRadius.circular(8))),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(Icons.countertops_outlined,
size: 20.0, color: Color(0xff279e23)),
const SizedBox(
width: 10,
),
Text(
"Pomodoro Counter",
style: TextStyle(fontSize: 14.0, color: Color(0xff279e23)),
),
],
),
onPressed: () async {
List pointsTake =
await this.authenticate.getPomoDoroCounter(this._userName);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PomoDoroSumUp(pointsTake)));
},
),
),
);
}
Future<void> clearCache(BuildContext context) async {
final cacheDir = await getTemporaryDirectory();
if (cacheDir.existsSync()) {
cacheDir.deleteSync(recursive: true);
}
Alert(
type: AlertType.success,
context: context,
title: "Cache Cleared",
style: AlertStyle(
alertBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
)).show();
}
}
I tried final String _userName but not luck,
in this line:
String _userName;
And also edit this line to see if it works adding a "!" but no luck
AccountInformation(this._userName, takeInformation!)));
What can I do in that case if I want to run the app with no problems? btw, im using flutter with android studio.
Thank you in advance
in AccountInformation class, I guess you defined your user name as List like this:
final List username;
if you want to pass username as string type
change it to:
final String username;
In PromoDoroClock the data type defined must be List but you are passing the _userName which is a string.

Image should be upload only that column which is clicked not in all and also explode blank image box

The image should be uploaded only to that column which is clicked not in all.
I write a code where I have columns in Gridviw and each column has the property to upload the image. The image will be uploaded on that column which is clicked but in my code when I click any column to upload an image it uploads in all columns. so I want to upload an image on a particular column that I click.
also when I upload an image and add a new column it adds a new box with an image, not blank box.
so please help me to do this.
Here is my code:-
import 'package:flutter/material.dart';
import 'package:/utils/widget_functions.dart';
import 'package:******/custom/BorderIcon.dart';
import 'package:******/screens/Relation.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'dart:io';
class Photos extends StatefulWidget {
var usrid;
Photos({Key? key, #required this.usrid}) : super(key: key);
#override
_Photos createState() => _Photos();
}
class _Photos extends State<Photos>{
PickedFile? _imageFile;
final String uploadUrl = 'https://api.imgur.com/3/upload';
final ImagePicker _picker = ImagePicker();
Future<String?> uploadImage(filepath, url) async {
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(await http.MultipartFile.fromPath('image', filepath));
var res = await request.send();
return res.reasonPhrase;
}
Future<void> retriveLostData() async {
final LostData response = await _picker.getLostData();
if (response.isEmpty) {
return;
}
if (response.file != null) {
setState(() {
_imageFile = response.file;
});
} else {
print('Retrieve error ${response.exception?.code}');
}
}
int counter = 0;
//List<Widget> _list = List<Widget>();
List<Widget> _list = <Widget> [];
List<PickedFile?> _images = [];
#override
void initState() {
for (int i = 0; i < 2; i++) {
Widget child = _newItem(i);
_list.add(child);
};
}
void on_Clicked() {
Widget child = _newItem(counter);
setState(
() => _list.add(child),
);
}
Widget _previewImage(int i) {
final _imageFile = this._imageFile;
if (_imageFile != null) {
return
SizedBox(
//width: 300,
height: 100,
child: Center(child:
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.file(
File(
_imageFile.path,
),
height: 80,
)
),
),
);
} else {
return InkWell(
onTap: () => _pickImage(i),
child: SizedBox(
//width: 300,
height: 100,
child: Center(child:
Icon(
Icons.image,
color: Color(0xffcccccc),
size: 60,
),
),
),
);
}
}
Widget _newItem(int i) {
Key key = new Key('item_${i}');
Column child = Column(
key: key,
children: [
Stack(
children: [
Card(
elevation: 0,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xffa1a1a1),
),
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: _previewImage(i),
),
Positioned(
top: 9,
right: 9,
child: InkWell(
onTap: () => _removeItem(i),
child: SvgPicture.asset(
width: 20,
'assets/images/close.svg',
height: 20,
),
),
)
]
),
]
);
counter++;
return child;
}
void _removeItem(int i) {
print("====remove $i");
print('===Removing $i');
setState(() => _list.removeAt(i));
}
void _pickImage( int i ) async {
try {
final pickedFile = await _picker.getImage(source: ImageSource.gallery);
setState(() {
_imageFile = pickedFile;
_images.add(pickedFile);
});
} catch (e) {
//print("Image picker error ${e!}");
print("Image picker error");
}
}
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
final ThemeData themeData = Theme.of(context);
final double padding = 25;
final sidePadding = EdgeInsets.symmetric(horizontal: padding);
var regID = widget.usrid;
return Theme(
data: ThemeData().copyWith(
dividerColor: Colors.transparent,
backgroundColor: Colors.transparent
),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: Builder(
builder: (BuildContext context) {
return Padding(padding: EdgeInsets.fromLTRB(15, 0, 0, 0),
child: IconButton(
icon: const Icon(
Icons.arrow_back_ios_outlined,
color: Colors.black,
),
onPressed: () { Navigator.pop(context); },
),
);
},
),
),
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
//colors: const [Color.fromRGBO(132,105,211,1), Color.fromRGBO(93,181,233,1), Color.fromRGBO(86,129,233,1)],
colors: [Colors.white, Colors.white]
),
),
width: size.width,
height: size.height,
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
addVerticalSpace(10),
Padding(
padding: sidePadding,
child: const Text(
'Add Your Photos',
style: TextStyle(
color: Colors.black,
fontSize: 20,
),),
),
addVerticalSpace(30),
Expanded(
child: Padding(
padding: sidePadding,
child: Column(
children: [
Expanded(
child: GridView(
//padding: const EdgeInsets.all(8.0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 15,
//childAspectRatio: 2/1,
),
// children: List.generate(_list.length, (index) {
// //generating tiles with people from list
// return _newItem(index);
// },
// ),
children: List.generate(_list.length + 1,
(index) => index == _list.length ?
InkWell(
onTap: () => on_Clicked(),
child: Column(
children: [
Stack(
children: const [
Card(
elevation: 0,
color: Color(0xff8f9df2),
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xff8f9df2),
),
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: SizedBox(
//width: 300,
height: 100,
child: Center(child:
Icon(
Icons.add,
color: Colors.white,
size: 80.0,
),
),
),
)
]
),
]
),
) :
_newItem(index)),
)
)
],
),
)
),
],
),
],
)
),
),
persistentFooterButtons:[
Padding(
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:[
ElevatedButton.icon( // <-- ElevatedButton
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back_ios_outlined,
size: 15.0,
color:Colors.white,
),
label: const Text(
'Back',
style: TextStyle(
fontSize: 20,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xffFDA766),
minimumSize: const Size(100, 49),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0),)
),
),
Directionality(
textDirection: TextDirection.rtl,
child: ElevatedButton.icon( // <-- ElevatedButton
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Relation(usrid:regID)),
);
},
icon: const Icon(
Icons.arrow_back_ios_outlined,
size: 15.0,
color:Colors.white,
),
label: const Text(
'Next',
style: TextStyle(
fontSize: 20,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xffFDA766),
minimumSize: const Size(100, 49),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0),)
),
),
),
]
),
),
]
),
);
}
}
And here is my output:- this is the output image before image upload
After image upload:- and this image after upload where it uploads all two columns
Please help me with how I solve this.

I have a problem with gridview display in flutter

You can see under my work, it is a lotto, a mini game in dart, user select 5 numbers and can validate his choice, the big 5 circles are the number selected but it is too too big and not render correctly in the blue rectangle :
I have a problem with the 5 Numbers in red just Under "Vos numéros", it is too big and i can't reduce the size in the code, it seems gridview adapt the size automatically, do you have any idea ?
import 'package:flutter/material.dart';
import 'dart:math';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'package:flutter_app/menu_member.dart';
import 'package:flutter_app/globals.dart' as globals;
class Lotto extends StatefulWidget {
#override
_LottoState createState() => new _LottoState();
}
class _LottoState extends State<Lotto> {
#override
void initState() {
super.initState();
}
var i=1;
var nb_num=49;
var no_select=[];
var no_a_select=5;
List<Color> colorList = List<Color>.generate(49, (int index) => Colors.lightBlue);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: new AppBar(
title: new Text('GRILLE DE LOTTO'),
),
body:
Center(
child: Column(
children: <Widget>[
Container(
width:400,
height:30,
margin: const EdgeInsets.only(top: 10.0),
child : new Text("Selectionnez 5 numéros",textAlign: TextAlign.center,style: TextStyle(fontSize: 30.0),),
),
Container(
width:400,
height:300,
child: new GridView.count(
crossAxisCount: 9,
padding: const EdgeInsets.all(30.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: new List<Widget>.generate(49, (index) {
return new GestureDetector(
onTap: () {
setState(() {
if (colorList[index] == Colors.lightBlue) {
if (no_select.length<no_a_select) {
colorList[index] = Colors.redAccent;
no_select.add(index+1);
}
else {
showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
title: Text("INFORMATION"),
content: Text("Vous ne pouvez pas sélectionner plus de 5 numéros !!!"),
);
}
);
}
print(no_select);
}
else {
colorList[index] = Colors.lightBlue;
no_select.remove(index+1);
print(no_select);
}
});
},
child: Container(
child: ClipOval(
child: Container(
color: colorList[index],
height: 20.0,
width: 20.0,
child: Center(
child: new Text((index+1).toString(),
style: TextStyle(color: Colors.white, fontSize: 24),
textAlign: TextAlign.center),
),
),
),
),
);
}
),
),
),
Container(
width:400,
height:30,
margin: const EdgeInsets.only(top: 10),
child : new Text("Vos Numéros",textAlign: TextAlign.center,style: TextStyle(fontSize: 30.0),),
),
Container(
width:400,
height:80,
margin: const EdgeInsets.only(top: 10.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.lightBlueAccent,
width: 2,
),
borderRadius: BorderRadius.circular(12),
),
child:
getWidget()
),
Container(
width:300,
height:45,
margin: const EdgeInsets.only(top: 10.0),
child:
RaisedButton(
color: Colors.green,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(9, 9, 9, 9),
child: Text('TIRAGE ALEATOIRE'),
onPressed: () {
Select_numbers();
},
),
),
Container(
width:300,
height:45,
margin: const EdgeInsets.only(top: 10.0),
child:
RaisedButton(
color: Colors.green,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(9, 9, 9, 9),
child: Text('VALIDER VOTRE GRILLE'),
onPressed: () {
Valide_grille();
},
),
),
]
)
),
),
);
}
getWidget() {
if (no_select.length==0) {
return Text("Pas de numéros");
}
else {
return GridView.count(
crossAxisCount: 5,
padding: const EdgeInsets.all(10.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: new List<Widget>.generate(no_select.length, (index) {
return ClipOval(
child: Container(
color: Colors.red,
height: 20.0,
width: 20.0,
child: Center(
child: new Text((no_select[index].toString()),
style: TextStyle(color: Colors.white, fontSize: 24),
textAlign: TextAlign.center),
),
),
);
}
)
);
}
}
Select_numbers() {
setState(() {
var j = 1;
var num_sel;
var pos_sel;
no_select=[];
colorList=[];
colorList=List<Color>.generate(49, (int index) => Colors.lightBlue);
var rng = new Random();
List tab=[];
tab = List.generate(49, (int index) => index + 1);
print (tab);
while (j <= no_a_select) {
pos_sel = rng.nextInt(tab.length-1);
num_sel=tab[pos_sel];
no_select.add(num_sel);
colorList[num_sel-1] = Colors.redAccent;
tab.remove(num_sel);
print(tab);
j++;
}
print(no_select);
});
}
Future Valide_grille() async{
// For CircularProgressIndicator.
bool visible = false ;
// Showing CircularProgressIndicator.
setState(() {
visible = true ;
});
// SERVER LOGIN API URL
var url = 'https://www.easytrafic.fr/game_app/valide_lotto.php';
// Store all data with Param Name.
var data = {'id_membre':globals.id_membre, 'result':no_select};
print (data);
var grille_encode=jsonEncode(data);
print(grille_encode);
// Starting Web API Call.
var response = await http.post(url, body: grille_encode,headers: {'content-type': 'application/json','accept': 'application/json','authorization': globals.token});
print(response.body);
// Getting Server response into variable.
var message = json.decode(response.body);
// If the Response Message is Matched.
if(message == 'OK')
{
print('VALIDATION DE LA GRILLE OK');
// Hiding the CircularProgressIndicator.
setState(() {
visible = false;
});
}else{
// Hiding the CircularProgressIndicator.
setState(() {
visible = false;
});
// Showing Alert Dialog with Response JSON Message.
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(message),
actions: <Widget>[
FlatButton(
child: new Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
}
It's because you put a Padding on your Gridview which make it scrollable
You can put the Padding to your ClipOval elements instead
return GridView.count(
crossAxisCount: 5,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: new List<Widget>.generate(
no_select.length,
(index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ClipOval(
child: Container(
color: Colors.red,
height: 20.0,
width: 20.0,
child: Center(
child: new Text((no_select[index].toString()),
style: TextStyle(color: Colors.white, fontSize: 24), textAlign: TextAlign.center),
),
),
),
);
},
),
);

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!