I have a form that allows the user to create addition cards at a tap of a button. Each card contains three form fields. How do i get the data from the forms to a json or to a list?
Hopefully get it to this format
"supplier_former_business": [
{
"name_of_company": "John Bull",
"year": 2018,
"amount": 28556
},
{
"name_of_company": "Gini Bull",
"year": 2019,
"amount": 1225
}
]
Here is the code that i have written so far but I am not sure how to get the values from the form fields in the cards.
class CustomerCurrentSuppliers extends StatefulWidget {
const CustomerCurrentSuppliers({Key key}) : super(key: key);
#override
_CustomerCurrentSuppliersState createState() => _CustomerCurrentSuppliersState();
}
class _CustomerCurrentSuppliersState extends State<CustomerCurrentSuppliers> {
int counter=1;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: kPrimaryColor,
title: const Text('Suppliers Data'),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
FloatingActionButton(
child: Icon(
Icons.arrow_forward
),
onPressed: () {
print(counter);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SupplierSchemeUnderConsideration()
),
);
//...
},
heroTag: null,
),
SizedBox(
height: 10,
),
FloatingActionButton(
child: Icon(
Icons.add
),
onPressed: () {
setState(() { //setState is used to update the UI
counter++;
});
},
heroTag: null,
)
]
),
body: Padding(
padding: const EdgeInsets.only(top: 38.0, right: 20, left: 20),
child: ListView.builder(
itemCount: counter, //updating counter will update the UI with new card
itemBuilder: (context,index){
return Card(
child:
Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: FormBuilderTextField(
name: 'Region',
decoration: InputDecoration(
labelText: "Supplier",
border: OutlineInputBorder()),
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(context),
]),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButtonHideUnderline(
child: FormBuilderDropdown(
name: 'dropdown',
hint: Text("Year"),
isExpanded: true,
items: [
"2018",
"2019",
"2020",
"2021",
].map((option) {
return DropdownMenuItem(
child: Text("$option"),
value: option,
);
}).toList(),
),
),
),
SizedBox(height: 20,),
Padding(
padding: const EdgeInsets.all(8.0),
child: FormBuilderTextField(
name: 'Region',
decoration: InputDecoration(
labelText: "Amount",
border: OutlineInputBorder()),
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(context),
]),
),
),
],
),
elevation: 8,
);
}),
),
);
}
}
I am passing a list of data that I called through API on 1st screen to 2nd screen and I am able to print all the data at once.
but now I want to use this data one by one and I don't know how to do that.... can you help?
this is the second screen -:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'Home_View.dart';
class AboutScreen extends StatefulWidget {
final data;
AboutScreen({Key key,#required this.data}) : super(key: key);
#override
_AboutScreenState createState() => _AboutScreenState(data:data);
}
class _AboutScreenState extends State<AboutScreen> {
var data;
_AboutScreenState({this.data});
int i = 0;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
print(data.toString()); // here i am printing all data
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 150, bottom: 40),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Card(
elevation: 25,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(65),
),
child: CircleAvatar(
child: Icon(Icons.insert_emoticon_outlined, size: 100,),
radius: 80,
foregroundColor: Colors.deepPurpleAccent,
),
),
],
),
),
Text(
'${data[0][i.toString()]}', // here i wanted to get data individually but it's showing error
style: TextStyle(
fontSize: 30,
letterSpacing: 2.5,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 30,),
Text(
'Version 2.2',
style: TextStyle(
fontSize: 20,
letterSpacing: 2.5,
),
),
SizedBox(height: 30,),
Text(
'Developed By Black Console',
style: TextStyle(
fontSize: 20,
letterSpacing: 2.5,
),
),
SizedBox(height: 40,),
FloatingActionButton(
child: Icon(Icons.arrow_back_ios),
backgroundColor: Colors.deepPurpleAccent,
elevation: 16,
onPressed: (){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => homeView()
));
},
),
],
),
);
}
}
below is the data that I am getting as a list -:
I/flutter ( 4689): {alternateno: [7845659877, 9865358577], coachaddress: [anand vihar, delhi, delhi, Gautam Budha nagar, noida], coachemail: [bct#gmail.com, SSG#gmail.com], coachid: [1, 2], coachname: [BCT Coaching, SSG Coaching], primary_number: [9865328899, 9898557898], userid: [1, 1]}
can you guide me please..
Your data variable seems to be a Map, not a list, so you can access its values like this:
data['alternateno'][i]
I need some help with this. My task is to pick the location along with the address and submit it. But for some reasons, the _addPointKey.currentState.validate() is always giving false.
I have a TextFormField for taking the address, a location preview container, a button to open the google_map_location_picker and finally a button to submit the data. All these fields are declared inside a form with _addPointKey key.
Form validation does work, i.e. if the fields are empty, it does show in red that the fields can't be empty. But still, I have some problem with submitting the whole formData. The textFormField becomes null.
I have used google_map_location_picker package for picking the location. Can somebody help?
Thanks in advance.
final GlobalKey<FormState> _addPointKey = GlobalKey<FormState>();
Map<String, dynamic> formData = {
"address": null,
};
Widget _addressField() {
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Address of the Collection Center",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Theme.of(context).primaryColor),
),
SizedBox(
height: 10,
),
TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Color(0xfff3f3f4),
filled: true),
maxLines: 4,
validator: (String value) {
if (value.isEmpty) {
return "Address is required";
}
return '';
},
onChanged: (String value) {
formData["address"] = value;
},
onSaved: (String value) {
formData["address"] = value;
},
),
],
),
);
}
Widget _locationPreview() {
return (_pickedLocation != null)
? Container(
height: 300,
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: Theme.of(context).accentColor,
)),
child: GoogleMap(
initialCameraPosition: CameraPosition(
target: _pickedLocation.latLng,
zoom: 14.4746,
),
markers: Set.from(newMarkers),
),
)
: Container(
child: Text(
"Location is required.",
style: TextStyle(
color: Colors.red,
),
),
);
}
Widget _locationButton() {
return RaisedButton(
color: Theme.of(context).accentColor,
onPressed: () async {
LocationResult result = await showLocationPicker(
context,
< API key>,
initialCenter: LatLng(31.1975844, 29.9598339),
myLocationButtonEnabled: true,
layersButtonEnabled: true,
);
setState(() {
_pickedLocation = result;
_addPointKey.currentState.save();
newMarkers.add(Marker(
markerId: MarkerId("newId"),
draggable: false,
position: _pickedLocation.latLng,
onTap: null,
));
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.location_on,
color: Colors.white,
),
Text(
(_pickedLocation == null) ? 'Locate on Map' : 'Change Location',
style: TextStyle(color: Colors.white),
),
],
),
);
}
Widget _addLocationButton() {
return ScopedModelDescendant<MainModel>(
builder: (BuildContext context, Widget widget, MainModel model) {
return model.managingCenter
? CircularProgressIndicator()
: InkWell(
onTap: () async {
print(_addPointKey.currentState.validate());
if (!_addPointKey.currentState.validate() ||
_pickedLocation == null) {
print(formData);
return;
}
_addPointKey.currentState.save();
Map<String, dynamic> successInfo =
await model.addCenter(model.token, formData);
if (successInfo["success"]) {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FutureBuilder(
future: model.fetchCenter(model.token),
builder: (context, authResultSnapShot) {
return authResultSnapShot.connectionState ==
ConnectionState.waiting
? SplashScreen()
: CollectionPoints(model);
})));
} else {
print("Something went wrong");
}
},
child: Container(
height: 50,
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.shade200,
offset: Offset(2, 4),
blurRadius: 5,
spreadRadius: 2)
],
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Color(0xfffbb448), Color(0xfff7892b)]),
),
padding: const EdgeInsets.all(10.0),
child: Text('Add the Location',
style: TextStyle(fontSize: 20, color: Colors.white)),
),
);
});
}
void _addPoint() {
showBottomSheet(
context: context,
builder: (context) {
return Container(
padding: EdgeInsets.all(10),
child: Form(
key: _addPointKey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
_addressField(),
_locationPreview(),
_locationButton(),
_addLocationButton()
],
),
),
),
);
});
}
In the TextFormField validator function you must return null, it indicates the field has correct value and there are no errors. Returning anything other than null will indicate that the field has an invalid value, i've shared the corrected code of the validator function.
TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Color(0xfff3f3f4),
filled: true),
maxLines: 4,
validator: (String value) {
if (value.isEmpty) {
return "Address is required";
}
// return ''; this is causing you the error you must return null
return null; // this is correct
},
onChanged: (String value) {
formData["address"] = value;
},
onSaved: (String value) {
formData["address"] = value;
},
),
A simpler way to create a confirm password on your flutter.
'showSnackBar' bottom pop-up to alert users for errors.
[1]: https://i.stack.imgur.com/zjXLd.png
var _password = '';
var _confirmPassword = '';
// this will called 'onTap'
void signUpUser() async {
if (_password != _confirmPassword){ // you can add your statements here
showSnackBar(context,
"Password does not match. Please re-type again.");
} else {
FirebaseAuthMethods(FirebaseAuth.instance).signUpWithEmail(
email: emailController.text,
password: passwordController.text,
context: context,
);
}
}
// Insert inside your build()
// to you password field.
child: TextFormField(
controller: passwordController,
obscureText: true,
onChanged: (value) {
_password = value;
},
// to your confirm password field.
child: TextFormField(
controller: confirmPasswordController,
obscureText: true,
onChanged: (value) {
_confirmPassword = value;
},
// add this to your Sign-up button
onTap: signUpUser,
I am new to flutter this error is giving me a serious nightmare. I have a card list of items called Anchors. These items are coming from the shared preference file which belongs to the logged-in user. In the shared preference Json file, each anchor has one or more distribution centers nested to it. All in a JSON form stored in the shared Preference. Now, I was able to iterate over the anchors respectfully at the first screen but the challenge I am having is when I click on view anchor details button instead of taking me to the details page where I can view the details of that anchor and iterate over the distribution centers of that anchor it doesn't but instead it takes the whole anchors there. I tried to parse only one id to the details page so I can Iterate over the nested objects of that anchor but still its not working. The error message says: type 'int' is not a subtype of type 'List' But if I remove [i]['Oid'] from the link to the details screen it takes the whole data there. They are all on two different screens. Please can anybody help me?
JSON format of:
"Anchors": [
{
"Oid": 11,
"Name": "MAIZE ASSOCIATION OF NIGERIA",
"Acronym": "MAAN",
"DistributionCentres": [
{
"Oid": 11,
"Name": "Logo Centre (Zone A)",
"Address": "Private Warehouse, Ugba, Logo LGA"
},
{
"Oid": 12,
"Name": "Makurdi Centre (Zone B)",
"Address": "Ministry of Agric, Makurdi "
},
{
"Oid": 13,
"Name": "Oturkpo Centre (Zone C)",
"Address": "Private Warehouse, Oturkpo"
},
{
"Oid": 15,
"Name": "Borno MAAN centre",
"Address": "Bolori Store, Flavour Mill, Behind Vita Foam, Maiduguri"
},
{
"Oid": 18,
"Name": "Bauchi Centre",
"Address": "BASPD, Dass Road, Bauchi"
}
],
"NoOfDistributionCentres": 5
},
{
"Oid": 2,
"Name": "MAIZE GROWERS, PROCESSORS AND MARKETERS ASSOCIATION OF NIGERIA",
"Acronym": "MAGPAMAN",
"DistributionCentres": [
{
"Oid": 2,
"Name": "Guma Centre",
"Address": "P 32, 2nd Avenue Federal Housing Estate, N/Bank, Makurdi"
},
{
"Oid": 3,
"Name": "Logo Centre",
"Address": "Terhemen Akema Storage Facility, Ugba, Logo LGA"
},
{
"Oid": 5,
"Name": "Oturkpo Centre",
"Address": "Grain Store, Lower Benue Okele Project, Otukpo"
},
{
"Oid": 6,
"Name": "Gboko Centre",
"Address": "K3 New Road, Opposite former coca cola plant. Solar Schools Street, Gboko"
},
{
"Oid": 7,
"Name": "Gwer East Centre",
"Address": "Ahua Shardye's Warehouse, Behind Sylkan Filling Station, Ikpayongo , G/East LGA"
},
{
"Oid": 8,
"Name": "Kwande Centre",
"Address": "KM 3, Adagi Road, Adikpo"
},
{
"Oid": 9,
"Name": "Ohimini Centre",
"Address": "Ajoga Oglewu, Ohimini"
},
{
"Oid": 10,
"Name": "Oju Centre",
"Address": "Behind Town Hall, Ohuhu owo, Oju LGA"
}
],
"NoOfDistributionCentres": 8
}
],
Anchors Page:
import 'package:erg_app/Details.dart';
import 'package:flutter/material.dart';
import 'package:erg_app/Widgets/nav-drawer.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(MaterialApp(
home: AnchorsPage(),
));
class AnchorsPage extends StatefulWidget {
#override
_MyHomeState createState() => _MyHomeState();
}
List<Anchor> _parseAnchors(Map<String, dynamic> map) {
final anchors = <Anchor>[];
for (var anchorMap in map['Anchors']) {
final anchor = Anchor.fromMap(anchorMap);
anchors.add(anchor);
}
return anchors;
}
class Anchor {
final int oId;
final String name;
final String acronym;
final List<DistributionCenter> distributionCenters;
const Anchor({
#required this.oId,
#required this.name,
#required this.acronym,
#required this.distributionCenters,
});
factory Anchor.fromMap(Map<String, dynamic> map) {
final distributionCenters = <DistributionCenter>[];
for (var distribution in map['DistributionCentres']) {
final distributionCenter = DistributionCenter.fromMap(distribution);
distributionCenters.add(distributionCenter);
}
return Anchor(
oId: map['Oid'] as int,
name: map['Name'] as String,
acronym: map['Acronym'] as String,
distributionCenters: distributionCenters,
);
}
}
class DistributionCenter {
final int id;
final String name;
final String address;
const DistributionCenter({
#required this.id,
#required this.name,
#required this.address,
});
factory DistributionCenter.fromMap(Map<String, dynamic> map) {
return DistributionCenter(
id: map['Oid'] as int,
name: map['Name'] as String,
address: map['Address'] as String,
);
}
}
class _MyHomeState extends State<AnchorsPage> {
var user;
var userData;
List anchors = [];
#override
void initState() {
_getUserAnchor();
super.initState();
}
_getUserAnchor() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var userJson = localStorage.getString('loginRes');
user = json.decode(userJson);
setState(() {
anchors = user['Anchors'];
});
print(anchors);
setState(() {
userData = anchors;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('Anchors Details'),
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
),
body: Container(
padding: const EdgeInsets.fromLTRB(10, 30, 10, 10),
child: ListView(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Icon(Icons.card_membership,
size: 35, color: Colors.orange[400]),
Text(
'Assigned Anchors',
style: TextStyle(color: Colors.orange[400], fontSize: 25),
),
],
),
ListView.builder(
shrinkWrap: true,
itemCount: anchors.length,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int i) {
return Padding(
padding: const EdgeInsets.all(10.0),
////////////// 1st card///////////
child: Card(
elevation: 4.0,
color: Colors.grey[100],
margin: EdgeInsets.only(
left: 10, right: 10, top: 20, bottom: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Container(
padding: EdgeInsets.only(left: 15, top: 20, bottom: 10),
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 50.0,
height: 50.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.cover,
image: AssetImage(
'assets/images/user.png')))),
),
SizedBox(
width: 20,
),
Text(
anchors[i]['Acronym'],
textAlign: TextAlign.center,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 20,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
],
),
Container(width: 10),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Allocated Farmers:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 70, top: 12),
child: Text(
anchors[i]['Oid'].toString(),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Validated Farmers:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 70, top: 12),
child: Text(
anchors[i]['Oid'].toString(),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Non Validated Farmers:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 40, top: 12),
child: Text(
anchors[i]['Oid'].toString(),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Distribution Centers:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 60, top: 12),
child: Text(
anchors[i]['Oid'].toString(),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Daily Inventory Status:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 50, top: 12),
child: Text(
'3',
textAlign: TextAlign.left,
style: TextStyle(
color:Colors.green,
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Container(
height: 20,
),
Row(
children: <Widget>[
/////////// Buttons /////////////
Padding(
padding: const EdgeInsets.all(10.0),
child: FlatButton(
child: Padding(
padding: EdgeInsets.only(
top: 8,
bottom: 8,
left: 10,
right: 8),
child: Text(
'View Details',
textDirection: TextDirection.ltr,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
color: Colors.blueGrey,
shape: new RoundedRectangleBorder(
borderRadius:
new BorderRadius.circular(
20.0)),
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
detailsPage(value : anchors[i]['Oid'])));
},
),
),
/////////// End of Buttons /////////////
],
),
],
),
),
),
);
})
],
),
),
);
}
}
Details Page:
import 'package:flutter/material.dart';
class detailsPage extends StatefulWidget {
List value;
detailsPage({Key key, #required this.value}) : super(key: key);
#override
_detailsPageState createState() => _detailsPageState(value);
}
class _detailsPageState extends State<detailsPage> {
List value;
_detailsPageState(this.value);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Anchors Details Page"),
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
),
body: Container(
child: ListView(
children: <Widget>[
Text(value[1]['Name']),
Text(value[1]['Oid'].toString()),
ListView.builder(
shrinkWrap: true,
itemCount: value[1]['DistributionCentres'].length,
//context:context, //it saying the name parameter context is not defined
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int i) {
return Text(value[1]['DistributionCentres'][i]['Name']);
})
],
),
),
);
}
}
Image of what I want to achieve below:
first screen onPressed get the index and assigned it to variable, or you can just pass i varibale too,
onPressed: () {
Navigator.push(context,new MaterialPageRoute(builder: (context) =>
detailsPage(i))); },
In detailed page
class detailsPage extends StatefulWidget {
final int selectedIndex;
detailsPage(this.selectedIndex,{Key key}) : super(key: key);
#override
_detailsPageState createState() => _detailsPageState();
}
place that you want to use the previous page passsed index,
return Text(value[widget.selectedIndex]['DistributionCentres'][i]['Name']);
Hope this will help..
The problem seems to be here
detailsPage(value : anchors[i]['Oid'])
You're passing Oid as parameter that is an Int. But look that the constructor for detailsPage
List value;
detailsPage({Key key, #required this.value}) : super(key: key);
The parameter value is a List. It's hard for me to know what you're trying to do... but you will need to fix this type mismatch.
EDIT
It seems that value parameter should be of type Map<String,dynamic>
class detailsPage extends StatefulWidget {
Map<String, dynamic> value;
detailsPage({Key key, #required this.value}) : super(key: key);
#override
_detailsPageState createState() => _detailsPageState(value);
}
class _detailsPageState extends State<detailsPage> {
Map<String, dynamic> value;
_detailsPageState(this.value);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Anchors Details Page"),
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
),
body: Container(
child: ListView(
children: <Widget>[
Text(value['Name']),
Text(value['Oid'].toString()),
ListView.builder(
shrinkWrap: true,
itemCount: value['DistributionCentres'].length,
//context:context, //it saying the name parameter context is not defined
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int i) {
return Text(value['DistributionCentres'][i]['Name']);
})
],
),
),
);
}
}
And then you should do
detailsPage(value : anchors[i])));
class GridDashboard extends StatefulWidget {
final Function onTap;
const GridDashboard({Key key, this.onTap}) : super(key: key);
#override
_GridDashboardState createState() => _GridDashboardState();
}
class _GridDashboardState extends State<GridDashboard> {
Items item1 = new Items(
title: 'Books',
img: 'assets/images/open-book.png',
onTap: () {
Books();
});
Items item2 = new Items(
title: 'Audio',
img: 'assets/images/headphones.png',
onTap: () => print('Audio')); // it works when I just print smth
Items item3 = new Items(
title: 'Videos',
img: 'assets/images/play-button.png',
onTap: () {
Videos();
});
#override
Widget build(BuildContext context) {
List<Items> myList = [item1, item2, item3];
return Flexible(
child: GridView.count(
childAspectRatio: 1.0,
padding: EdgeInsets.only(left: 30, right: 20, top: 220),
crossAxisCount: 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
children: myList.map((data) {
return GestureDetector(
onTap: data.onTap, // this line is not working
child: Container(
decoration: BoxDecoration(
color: Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(35),
boxShadow: [
BoxShadow(
color: Color(0xFF373234),
blurRadius: 6.0,
offset: Offset(0, 2),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(data.img, width: 45),
SizedBox(height: 15),
Text(
data.title,
style: GoogleFonts.openSans(
textStyle: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
],
),
),
);
}).toList(),
),
);
}
}
class Items {
String title;
String img;
Function onTap;
Items({this.img, this.title, this.onTap});
}
Hi people.
I am building an android app. The above code is for a dashboard (menu) section of my code. The GestureDetector onTap function is not working when I want it to go to another screen. But it works if I just want to print out smth. If you know how to solve this issue can you please help here ?
Thank you.
You can use named routes.
For Example :
Add the routes to you MaterialApp
void main() {
runApp(MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => FirstScreen(),
'/books': (context) => Books(),
'/videos': (context) => Videos(),
},
));
}
Change onTap to go to the specific page
onTap: () {
Navigator.pushNamed(context, '/books');
});
Make changes to the widgets accordingly.