Related
I'm getting a desync behavior with ListView.builder, TextField, and TextEditingController.
When I'm adding/removing an "issue" object the text that I see once I tap the issue is "shifted" one down or just way wrong, but the controller still affects the same object.
I'm adding pictures for clarification:
So here you can see all the objects
Once i tap say the first top one "5"
Now i add an new "issue" object
Then i click again on the object i clicked before "5" which is the second top one now:
I cant seem to understand why this behavoir happens and how to fix it.
finally im posting my code for more refrense:
// ignore_for_file: non_constant_identifier_names, sized_box_for_whitespace
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:dronebag/app.dart';
import 'package:dronebag/config/font_size.dart';
import 'package:dronebag/domain/battery_issue_repository/battery_issue_repository.dart';
import 'package:dronebag/domain/battery_repository/battery_repository.dart';
import 'package:dronebag/domain/battery_station_issue_repository/battery_station_issue_repository.dart';
import 'package:dronebag/domain/battery_station_repository/src/models/models.dart';
import 'package:flutter/gestures.dart';
import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import '../widgets/widgest.dart';
class BatteryStationDetails extends StatefulWidget {
final String groupID;
final BatteryStation batteryStation;
const BatteryStationDetails({
Key? key,
required this.groupID,
required this.batteryStation,
}) : super(key: key);
#override
State<BatteryStationDetails> createState() => _BatteryStationDetailsState();
}
class _BatteryStationDetailsState extends State<BatteryStationDetails> {
final formKey = GlobalKey<FormState>();
final TextEditingController serial_numberController = TextEditingController();
final TextEditingController batteryIssueDetailController =
TextEditingController();
final TextEditingController batteryCycleController = TextEditingController();
final TextEditingController date_boughtController = TextEditingController();
final double sizedBoxHight = 16;
final TextEditingController battery_pairsController = TextEditingController();
#override
void initState() {
// ignore: todo
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
final fetch = FirestoreFetch(
groupID: widget.groupID, batteryStation: widget.batteryStation);
final create = FirestoreCreate(
groupID: widget.groupID, batteryStation: widget.batteryStation);
return Scaffold(
appBar: AppBar(
backgroundColor: ThemeColors.scaffoldBgColor,
title: Text(
"Battery Station ${widget.batteryStation.serial_number}",
style: GoogleFonts.poppins(
color: ThemeColors.whiteTextColor,
fontSize: FontSize.xxLarge,
fontWeight: FontWeight.w600,
),
),
actions: [
TextButton(
child: Text(
'Edit Station \nDetails',
textAlign: TextAlign.center,
style: GoogleFonts.poppins(
color: Colors.blue,
fontSize: FontSize.medium,
fontWeight: FontWeight.w600,
),
),
onPressed: () {
showDialog(
context: context,
builder: (context) => EditBatteryStationDialog(
batteryStation: widget.batteryStation,
groupID: widget.groupID,
));
},
),
],
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(38),
child: Column(children: [
Text(
'Batteries',
style: GoogleFonts.poppins(
color: ThemeColors.textFieldHintColor,
fontSize: FontSize.large,
fontWeight: FontWeight.w600,
),
),
StreamBuilder<List<Battery>>(
stream: fetch.fetchBatteries(),
builder: ((context, snapshot) {
if (snapshot.hasData) {
final batteries = snapshot.data!;
batteries.sort(
(a, b) {
return a.serial_number.compareTo(b.serial_number);
},
);
return GridView.builder(
physics: const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.8,
),
itemCount: batteries.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return BatteryTile(
battery: batteries[index],
batteryStation: widget.batteryStation,
groupID: widget.groupID);
},
);
} else if (snapshot.hasError) {
return SingleChildScrollView(
child: Text('Something went wrong! \n\n$snapshot',
style: const TextStyle(color: Colors.white)),
);
} else {
return const Center(child: CircularProgressIndicator());
}
})),
const SizedBox(height: 20),
RichText(
text: TextSpan(
children: [
TextSpan(
style: GoogleFonts.poppins(
color: ThemeColors.textFieldHintColor,
fontSize: FontSize.large,
fontWeight: FontWeight.w600,
),
text: "Station\'s Issue list ",
),
const WidgetSpan(
child: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
)),
TextSpan(
recognizer: TapGestureRecognizer()
..onTap = () {
create.createBatteryStationIssue();
},
text: 'Add Issue',
style: GoogleFonts.poppins(
color: ThemeColors.primaryColor,
fontSize: FontSize.medium,
fontWeight: FontWeight.w600,
),
)
],
),
),
SizedBox(height: 12),
//vvvvvvvvvvvvvvvvvvRELEVENTvvvvvvvvvvvvvvvvvvvv//
StreamBuilder<List<BatteryStationIssue>>(
stream: fetch.fetchBatteryStationIssue(),
builder: ((context, snapshot) {
if (snapshot.hasData) {
final batteryStationIssues = snapshot.data!;
//print(issues.length);
return Container(
child: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: batteryStationIssues.length,
itemBuilder: (context, index) {
print("==========");
return BatteryStationIssueTile(
groupID: widget.groupID,
batteryStation: widget.batteryStation,
batteryStationIssue: batteryStationIssues[index]);
},
),
);
} else if (snapshot.hasError) {
return SingleChildScrollView(
child: Text('Something went wrong! \n\n$snapshot',
style: const TextStyle(color: Colors.white)),
);
} else {
return const Center(child: CircularProgressIndicator());
}
}),
),
]),
),
));
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:dronebag/config/font_size.dart';
import 'package:dronebag/config/theme_colors.dart';
import 'package:dronebag/domain/battery_station_issue_repository/battery_station_issue_repository.dart';
import 'package:dronebag/domain/battery_station_repository/battery_station_repository.dart';
import 'package:dronebag/widgets/utils.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class BatteryStationIssueTile extends StatefulWidget {
final String groupID;
final BatteryStation batteryStation;
final BatteryStationIssue batteryStationIssue;
const BatteryStationIssueTile({
Key? key,
required this.groupID,
required this.batteryStation,
required this.batteryStationIssue,
}) : super(key: key);
#override
State<BatteryStationIssueTile> createState() =>
_BatteryStationIssueTileState();
}
class _BatteryStationIssueTileState extends State<BatteryStationIssueTile> {
TextEditingController batteryStationIssueDetailController =
TextEditingController();
#override
void initState() {
batteryStationIssueDetailController =
TextEditingController(text: widget.batteryStationIssue.detail);
super.initState();
}
#override
void dispose() {
batteryStationIssueDetailController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
String issueDescription = widget.batteryStationIssue.detail;
Color textDescriptionColor = ThemeColors.whiteTextColor;
if (widget.batteryStationIssue.detail == "") {
issueDescription = "Click me to add description";
textDescriptionColor = ThemeColors.greyTextColor;
}
print("Issue:");
print(widget.batteryStationIssue.detail);
return ListTile(
onTap: (() {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: ThemeColors.scaffoldBgColor,
scrollable: true,
title: Center(
child: Text(
"Edit issue description",
style: GoogleFonts.poppins(
color: ThemeColors.whiteTextColor,
fontSize: FontSize.large,
fontWeight: FontWeight.w600,
),
),
),
content: TextFormField(
controller: batteryStationIssueDetailController,
keyboardType: TextInputType.multiline,
maxLines: null,
style: GoogleFonts.poppins(
color: ThemeColors.whiteTextColor,
fontSize: FontSize.medium,
fontWeight: FontWeight.w400,
),
decoration: InputDecoration(
fillColor: ThemeColors.textFieldBgColor,
filled: true,
hintText: "Issue description",
hintStyle: GoogleFonts.poppins(
color: ThemeColors.textFieldHintColor,
fontSize: FontSize.small,
fontWeight: FontWeight.w400,
),
border: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(18)),
),
),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Cancel')),
TextButton(
onPressed: () {
final docBatteryStationIssue = FirebaseFirestore.instance
.collection('groups')
.doc(widget.groupID)
.collection('battery_stations')
.doc(widget.batteryStation.id)
.collection('issues')
.doc(widget.batteryStationIssue.id);
docBatteryStationIssue.update(
{'detail': batteryStationIssueDetailController.text});
Navigator.pop(context);
Utils.showSnackBarWithColor(
'Issue has been updated', Colors.blue);
},
child: const Text(
'Update issue',
style: TextStyle(color: Colors.blue),
)),
],
),
);
}),
title: Padding(
padding: const EdgeInsets.all(0),
child: Container(
decoration: const BoxDecoration(
color: Color.fromARGB(255, 32, 32, 32),
borderRadius: BorderRadius.all(Radius.circular(5))),
child: Center(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 5, 8, 5),
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
'${widget.batteryStationIssue.date.day}-${widget.batteryStationIssue.date.month}-${widget.batteryStationIssue.date.year}',
style: GoogleFonts.poppins(
color: ThemeColors.whiteTextColor,
fontSize: FontSize.medium,
fontWeight: FontWeight.w400,
),
),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
issueDescription,
style: GoogleFonts.poppins(
color: textDescriptionColor,
fontSize: FontSize.medium,
fontWeight: FontWeight.w400,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
'Status: ${widget.batteryStationIssue.status}',
style: GoogleFonts.poppins(
color: ThemeColors.whiteTextColor,
fontSize: FontSize.medium,
fontWeight: FontWeight.w400,
),
),
),
Align(
alignment: Alignment.centerRight,
child: IconButton(
iconSize: 24,
splashColor: Colors.transparent,
color: Colors.red,
icon: const Icon(Icons.delete),
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: ThemeColors.scaffoldBgColor,
title: Center(
child: Text(
"Delete this issue?",
style: GoogleFonts.poppins(
color: ThemeColors.whiteTextColor,
fontSize: FontSize.large,
fontWeight: FontWeight.w600,
),
),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text(
'Cancle',
style: TextStyle(color: Colors.blue),
)),
TextButton(
onPressed: () {
FirebaseFirestore.instance
.collection('groups')
.doc(widget.groupID)
.collection('battery_stations')
.doc(widget.batteryStation.id)
.collection("issues")
.doc(
widget.batteryStationIssue.id)
.delete();
Navigator.pop(context);
},
child: const Text(
'Yes Delete',
style: TextStyle(color: Colors.red),
)),
]),
);
},
),
),
],
),
],
),
),
),
),
),
);
}
}
To keep things short:
I have multiple products, where you can increment and decrement their value(qnty) inside the cart and after Submitting, a receipt is generated based on the cart Items.
So the Problem is whenever I try to slide the submit, the qnty of the first product I added to cart is assigned to every product, Like
• Apple: 1
• Mango: 2
• Orange: 6
Above is how it should be like
• Apple: 6
• Mango: 6
• Orange: 6
This is the result I am getting, Note: The Result is from new to old
Secondary issue is that whenever I try to write any value inside the textfield and click submit, the value still doesn't get updated!
The Code consists of 2 files:
Parent File
import 'package:ambica_medico/component/result/productcart.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:whatsapp_unilink/whatsapp_unilink.dart';
import '../../component/buttons/c_button.dart';
import '../../constant.dart';
final FirebaseAuth auth = FirebaseAuth.instance;
Stream<QuerySnapshot> getData() => FirebaseFirestore.instance
.collection('Users')
.doc(auth.currentUser?.uid)
.collection('Carts')
.snapshots();
class Cart extends StatefulWidget {
const Cart({Key? key}) : super(key: key);
#override
State<Cart> createState() => _CartState();
}
class _CartState extends State<Cart> {
String _text = '';
callback(newAbc) {
pk = newAbc;
} //Step 5: Callback ready to be passed to the the Procart.
String? product;
String qnty = '';
String? mail;
String? name;
String? address;
String? dln;
String? gst;
late final _getData = getData();
DateTime now = DateTime.now();
Map<String, String> pk = {};
#override
Widget build(BuildContext context) {
return StreamBuilder<dynamic>(
stream: _getData,
builder: (context, snapshot) {
final tilesList = <Widget>[];
if (snapshot.hasData) {
snapshot.data.docs.forEach((value) {
qnty = value.data()['SIB'].toString();
pk = {value.id: qnty}; //Step4: A map which holds every product id and qnty
final productTile = Procart(
pname: value.data()['Product'],
subtitle: value.data()['MRP'],
keyo: value.id,
controller: qnty, sib: value.data()['OSIB'], tis: value.data()['TIS'], callback: callback, //Callback passed!
);
if (_text.isEmpty) {
tilesList.add(productTile);
} else {
if (value
.data()['Product']
.toUpperCase()
.contains(_text.toUpperCase())) {
tilesList.add(productTile);
}
}
// print(pk.values); //Returns 5,1
});
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: Padding(
padding: const EdgeInsets.only(left: 20.0, top: 10),
child: IconButton(
icon: const Icon(
Icons.arrow_back_ios_new_rounded,
color: Colors.black,
size: 20,
),
onPressed: () {
Navigator.pop(context);
},
),
),
backgroundColor: const Color(0xFFf5f3f7),
elevation: 0,
),
body: GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Container(
decoration: kImageBackground.copyWith(),
height: MediaQuery.of(context).size.height,
child: Stack(children: [
Column(
children: [
SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(
left: 24.0, right: 24.0, top: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text(
'The Cart',
style: TextStyle(
fontSize: 40,
fontFamily: 'ProductSans',
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
Padding(
padding:
const EdgeInsets.only(top: 50, bottom: 50),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Color(0x261B1B1A),
blurRadius: 50.0,
spreadRadius: 0,
offset: Offset(0.0, 30.0),
),
],
),
height: 70,
child: Center(
child: TextField(
onChanged: (value) {
setState(() {
_text = value;
});
},
keyboardType: TextInputType.text,
decoration: kDecorS.copyWith(
hintText: 'Search Products',
),
style: const TextStyle(
fontFamily: 'ProductSans',
fontSize: 18,
fontWeight: FontWeight.w400,
color: Color(0xff0f1511),
),
),
),
),
),
],
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.55,
child: ListView(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
children: tilesList,
),
),
],
),
Positioned(
bottom: 0,
child: SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(42.0),
topRight: Radius.circular(42.0),
),
color: Colors.white,
),
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Column(
children: [
const Padding(
padding:
EdgeInsets.only(bottom: 10.0),
child: Center(
child: Text(
'Check and then click below to',
style: TextStyle(
fontSize: 14,
fontFamily: 'ProductSans',
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
),
Cbutton(
text: 'Send Order',
onPressed: () async {
String message = "";
DateTime date = DateTime(
now.year, now.month, now.day);
await FirebaseFirestore.instance
.collection('Users')
.doc(auth.currentUser?.uid)
.get()
.then((value) => {
name = value.data()!['name'],
address =
value.data()!['address'],
dln = value.data()!['dln'],
gst = value.data()!['gst'],
});
await snapshot.data.docs
.forEach((value) async {
product = value.data()['Product'];
message += '- $product = ${pk.values} \n';
});
final Email email = Email(
body:
"From:- \n\nName: $name\n\nAddress: $address\n\nDrug License No:- $dln\n\nGST No:- $gst\n\nDate:- $date \n\nDear sir,\nPlease dispatch my following order earliest possible through\n $message \n\nThanks & Regards,\n$name",
subject: 'Order Detail',
recipients: ['calagency03#gmail.com'],
isHTML: false,
);
final link = WhatsAppUnilink(
phoneNumber: '+91 2313210000',
text:
"From:- \n\nName: $name\n\nAddress: $address\n\nDrug License No:- $dln\n\nGST No:- $gst\n\nDate:- $date \n\nDear sir,\nPlease dispatch my following order earliest possible through\n $message \n\nThanks & Regards,\n$name",
);
await FlutterEmailSender.send(email);
final url = Uri.parse('$link');
await launchUrl(url, mode: LaunchMode.externalApplication,);
},
icon: const Icon(
Icons.send_rounded,
color: Colors.black,
size: 20,
),
color: const Color(0xff0f1511),
),
],
),
),
),
),
),
)
]),
),
),
),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
});
}
}
The main logic of printing the receipt for a product is:
await snapshot.data.docs
.forEach((value) async {
product = value.data()['Product'];
message += '- $product = ${pk.values} \n';
});
Child File
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
class Procart extends StatefulWidget {
final String pname;
final String subtitle;
final String keyo; // Step1: Product id
final String sib;
final String tis;
final String controller; // Step2: Initial Value/ Qnty
final Function(Map) callback; // Step3: Callback to parents widget in which it passes updated qnty
const Procart(
{Key? key,
required this.pname,
required this.subtitle,
required this.keyo, required this.controller, required this.sib, required this.tis, required this.callback})
: super(key: key);
#override
State<Procart> createState() => _ProcartState();
}
class _ProcartState extends State<Procart> {
final FirebaseAuth auth = FirebaseAuth.instance;
late TextEditingController controller = TextEditingController(text: widget.controller);
Map<String, String> lk = {};
sub() {
setState(() {
controller.text =
(int.parse(controller.text) - 1).toString();
});
}
add() {
setState(() {
controller.text =
(int.parse(controller.text) + 1).toString();
});
}
// #override
// void didUpdateWidget(covariant Procart oldWidget) {
// // TODO: implement didUpdateWidget
// super.didUpdateWidget(oldWidget);
//
//
// }
#override
Widget build(BuildContext context) {
lk = { widget.keyo : controller.text }; // This map is used to store updated value
widget.callback(lk); // send updated value back to parent class but the value still remains 2,2,2 instead of 1,7,2
print(lk.values);
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Slidable(
key: Key(widget.keyo),
endActionPane: ActionPane(motion: const ScrollMotion(), children: [
SlidableAction(
// An action can be bigger than the others.
onPressed: (value) {
FirebaseFirestore.instance
.collection('Users')
.doc(auth.currentUser?.uid)
.collection('Carts')
.doc(widget.keyo)
.delete();
},
backgroundColor: const Color(0xFFD16464),
foregroundColor: Colors.white,
icon: Icons.clear_rounded,
),
]),
child: Padding(
padding: const EdgeInsets.only(left: 28.0, right: 28.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.pname,
style: const TextStyle(
fontFamily: 'Satoshi',
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xff0f1511),
),
),
Text(
'${widget.subtitle} | ${widget.sib} x ${widget.tis}',
style: const TextStyle(
fontFamily: 'Satoshi',
fontSize: 12,
fontWeight: FontWeight.normal,
color: Color(0xff0f1511),
),
),
],
),
),
Row(
children: [
CircleAvatar(
radius: 16,
backgroundColor: const Color(0xff1b1b1b),
child: IconButton(
iconSize: 13,
icon: const Icon(
Icons.remove,
color: Colors.white,
),
onPressed: () {
if (int.parse(controller.text) >
int.parse(widget.sib)) {
sub();
}
},
),
),
SizedBox(
width: 80,
child: TextFormField(
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(left: 6, right: 6),
),
controller: controller,
onEditingComplete: () {
controller;
},
keyboardType: TextInputType.number,
style: const TextStyle(
fontFamily: 'Satoshi',
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Color(0xff0f1511),
),
),
),
CircleAvatar(
radius: 16,
backgroundColor: const Color(0x33bababa),
child: IconButton(
iconSize: 13,
icon: const Icon(
Icons.add,
color: Color(0xff1b1b1b),
),
onPressed: () {
add();
},
),
),
],
),
]),
),
),
))),
);
}
}
For more info I have attached Screenshots below:
A Huge Thank you to anyone who helps me in solving this!
Well, I solved this issue by following the steps below:
hello can someone help me on nested listview.
as you can see from the image below, i made two listview.builders.
first listview.builder(context, i) is for the headers "ChildWO:" and a description below.
Than another listview.builder(context, index) for under it that contains data about it (shown in card widgets).
My problem is, whenever I input a value inside the textfield.
every textfield that have the same position will be filled up.
for example "55". every first card of it will be filled with "55".
Is there a way wherein I can set the controller of the textfield to have it like,
"controller: _qtyInputtedList[i][index]"?
for now, my controller is set at controller: _qtyInputtedList[index].
Thank you.
Expanded(
child: Container(
decoration: BoxDecoration(color: Colors.white),
child: ListView.separated(
physics: const AlwaysScrollableScrollPhysics(),
separatorBuilder: (context, index) => SizedBox(
height: 1,
),
itemCount: mainParent.CHILDREN?.length ?? 0,
itemBuilder: (context, i) {
// _qtyInputtedList.add(new TextEditingController());
return Padding(
padding: EdgeInsets.fromLTRB(2, 10, 2, 0),
child: Column(
children: <Widget>[
Text(
'Child WO: ${mainParent.CHILDREN![i].WONUM}',
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: 'NunitoLight'),
),
Padding(
padding:
EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Text(
'${mainParent.CHILDREN![i].WODESC}',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 15.0,
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: 'NunitoLight'),
),
),
ListView.builder(
itemCount: mainParent
.CHILDREN![i].MATERIALS!.length,
itemBuilder: (context, index) {
_qtyInputtedList.add(new TextEditingController());
final post = mainParent
.CHILDREN![i].MATERIALS![index];
//tileKey.add(GlobalKey(debugLabel: "index :$i"));
return Padding(
padding: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"1"
? const EdgeInsets.fromLTRB(
10, 4, 10, 4)
: const EdgeInsets.fromLTRB(
20, 4, 10, 4),
child: GestureDetector(
onLongPress: () {
//itemNum will be used for component list endpoint
itemNum =
'${mainParent.CHILDREN![i].MATERIALS![index].ITEMNUM}';
mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"1"
? _displayDialogListMaterials(
context)
: null;
},
child: ExpansionTileCard(
//key: tileKey[i],
//key: tileKey[i],
//baseColor: Colors.grey[800],
baseColor: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"1"
? Color(0xff3A3845)
: Color(0xff826F66),
// baseColor: Colors.red[700],
expandedTextColor:
Colors.black,
expandedColor: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"1"
? Color(0xff3A3845)
: Colors.grey[600],
trailing: Transform.scale(
scale: 2.5,
child: Theme(
data: ThemeData(
unselectedWidgetColor:
Colors.grey[
700], // Your color
),
child: Container(
margin:
EdgeInsets.all(10),
width: 14,
height: 14,
color: Colors.white,
child: Checkbox(
hoverColor:
Colors.white,
activeColor: Colors
.green[700],
value:
selectedItems.contains(mainParent
.CHILDREN![i]
.MATERIALS![index]),
onChanged:
(bool? value) {
if(selectedItems.contains(mainParent
.CHILDREN![i]
.MATERIALS![index])) {
selectedItems.remove(mainParent
.CHILDREN![i]
.MATERIALS![index]);
selectedItems.remove(mainParent
.CHILDREN![i]
.MATERIALS![index].ITEMNUM);
selectedItems.remove(mainParent
.CHILDREN![i]
.WONUM);
selectedItems.remove(_qtyInputtedList[index].text);
} else {
selectedItems.add(mainParent
.CHILDREN![i]
.MATERIALS![index]);
selectedItems.add(mainParent
.CHILDREN![i]
.MATERIALS![index].ITEMNUM);
selectedItems.add(mainParent
.CHILDREN![i]
.WONUM);
selectedItems.add(_qtyInputtedList[index].text);
}
setState(() {
print(selectedItems.toString());
//if you want to reload loadparent2
// dataFuture = loadParent2();
});
}),
),
),
),
// leading: Icon(
// Icons.warning_amber,
// color: Colors.white,
// size: 60.0,
// ),
leading: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"0"
? Container(
width: 60.0,
child: TextField(
controller: _qtyInputtedList[index],
keyboardType:
TextInputType
.number,
style: TextStyle(
fontSize: 20),
decoration:
InputDecoration(
filled: true,
fillColor:
Colors.white,
border:
InputBorder
.none,
),
),
)
: null,
title: Text(
'${mainParent.CHILDREN![i].MATERIALS![index].ITEMNUM}',
style: Theme.of(context)
.textTheme
.bodyText2!
.copyWith(
fontSize: 25,
color: Colors.white,
fontWeight:
FontWeight
.bold),
),
subtitle: Text(
'${mainParent.CHILDREN![i].MATERIALS![index].ITEMDESCRIPTION}',
style: Theme.of(context)
.textTheme
.bodyText2!
.copyWith(
fontSize: 16,
color:
Colors.white),
),
children: mainParent
.CHILDREN![i]
.MATERIALS![index]
.STRUCTURE ==
"0"
? <Widget>[
Divider(
thickness: 3.0,
height: 3.0,
),
Align(
alignment: Alignment
.centerLeft,
child: Padding(
padding:
const EdgeInsets
.symmetric(
horizontal:
16.0,
vertical: 5.0,
),
child: Text(
"Planned QTY: ${mainParent.CHILDREN![i].MATERIALS![index].QUANTITYPLAN}"
"\n"
"Warehouse Balance: 30",
style: Theme.of(
context)
.textTheme
.bodyText2!
.copyWith(
fontSize:
22),
),
),
),
ButtonBar(
alignment:
MainAxisAlignment
.start,
buttonHeight: 52.0,
buttonMinWidth:
90.0,
children: <
Widget>[],
),
]
: <Widget>[])),
);
},
shrinkWrap: true,
physics: ClampingScrollPhysics(),
)
],
),
);
}),
),
),
I recommend you to split your code to reuseable widgets, by this way you don't need to care about controller and how to declare it they are differences, code look short and clearly, below is example.
Example:
import 'package:flutter/material.dart';
class Student {
int id;
String name;
Student(this.id, this.name);
}
class Class {
String name;
List<Student> students;
Class(this.name, [this.students = const []]);
}
class RenderStudent extends StatefulWidget {
const RenderStudent({required this.student, Key? key}) : super(key: key);
final Student student;
#override
RenderStudentState createState() => RenderStudentState();
}
class RenderStudentState extends State<RenderStudent> {
Student get student => widget.student;
late TextEditingController controller;
#override
void initState() {
controller = TextEditingController(text: widget.student.name);
controller.addListener(() => setState(() {}));
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return TextField(
controller: controller,
decoration: InputDecoration(
labelText: "Student id: ${student.id}",
border: const OutlineInputBorder(),
),
);
}
}
class RenderClass extends StatelessWidget {
const RenderClass({required this.clas, Key? key}) : super(key: key);
final Class clas;
#override
Widget build(BuildContext context) {
return Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text("Class ${clas.name}", style: const TextStyle(fontSize: 40)),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: clas.students.length,
itemBuilder: (context, i) => Padding(
padding: const EdgeInsets.all(4),
child: RenderStudent(
student: clas.students[i],
),
),
),
],
),
);
}
}
void main() {
final items = [
Class('A1', [Student(1, "Carter")]),
Class('B1', [Student(2, "Join"), Student(2, "Smith"), Student(2, "Lara")]),
];
return runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, i) => RenderClass(clas: items[i]),
),
),
),
);
}
I have a search screen where users can search for a county and a list of vaccination posts in said county is shown. Some counties have many some have very few.
In the list of vaccination posts, there is a button that when pressed, the button is disabled. All is good until here, but when I re-search the same county, the button that was once disabled is no longer disabled, meaning it can be pressed again. I would like to avoid that.
I have a list of bools, "true" for each vaccination post. When button is pressed, respective index in the list is changed to "false" thus disabling the button.
Question: How can I keep the button disable? (Whether the same county is re-searched or the app is re-opened)
import 'package:colour/colour.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
// import 'package:shared_preferences/shared_preferences.dart';
class VaccineCenterList extends StatefulWidget {
const VaccineCenterList({key}) : super(key: key);
static const String idScreen = "VaccineCenterList";
#override
_VaccineCenterListState createState() => _VaccineCenterListState();
}
class _VaccineCenterListState extends State<VaccineCenterList> {
TextEditingController hospitalCountyEditingController =
TextEditingController();
final databaseReference = FirebaseDatabase.instance.reference();
final firestoreInstance = FirebaseFirestore.instance;
FirebaseAuth auth = FirebaseAuth.instance;
List<Hospitals> driverList = [];
List<bool> buttonPressed = [];
// Map<String, List> buttonPressed = {};
buttonControls(numOfLocations) {
print(numOfLocations);
int checker = 0;
if (numOfLocations > buttonPressed.length) {
try {
while (numOfLocations >= checker) {
buttonPressed.add(true);
checker = checker + 1;
}
} catch (e) {
print("$e");
}
} else {}
print(buttonPressed);
}
#override
void initState() {
super.initState();
print("I'm in the vaccine list search screen");
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
backgroundColor: Colors.grey[100],
centerTitle: true,
elevation: 0,
iconTheme: const IconThemeData(
color: Colors.black,
),
title: Text(
"Pamoja",
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 35,
),
),
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: SingleChildScrollView(
child: Column(
children: [
Container(
// textfield
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: hospitalCountyEditingController,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.words,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
style: BorderStyle.solid,
width: 1,
),
),
labelText: "Search County",
labelStyle: const TextStyle(
fontSize: 14.0,
color: Colors.blueGrey,
),
hintStyle: GoogleFonts.lexendMega(
color: Colors.grey,
fontSize: 10,
),
),
style: GoogleFonts.lexendMega(
fontSize: 14,
color: Colors.black,
),
),
),
ElevatedButton(
// search button
onPressed: () {
setState(() {
FocusScope.of(context).requestFocus(
FocusNode(),
);
driverList.clear();
if (hospitalCountyEditingController.text == "" ||
hospitalCountyEditingController.text == " ") {
isTrueOrFalse = "False";
} else {
isTrueOrFalse = "True";
}
});
getHospitalDetails();
},
child: Text(
"Search",
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
),
),
),
SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height,
// height: 50,
// color: Colors.black,
child: Padding(
padding: const EdgeInsets.only(
right: 12.0,
left: 12.0,
bottom: 12.0,
),
child: driverList.isEmpty
? Center(
// child: CircularProgressIndicator(),
child: (isTrueOrFalse == "True")
? const CircularProgressIndicator()
: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Search for one of the counties below",
style:
GoogleFonts.lexendMega()),
),
Text(
"Nairobi, Baringo, Busia, Bomet, Bungoma, Elgeyo Marakwet, Embu, Garissa, Homa Bay, Isiolo, Kajiado, Kakamega, Kericho, Kiambu, Kilifi, Kirinyaga, Kisii, Kisumu, Kitui, Kwale, Laikipia, Lamu, Machakos, Makueni, Mandera, Marsabit, Meru, Migori, Mombasa, Muranga, Nakuru, Nandi, Narok, Nyamira, Nyandarua, Nyeri, Samburu, Siaya County, Taita Taveta, Tana River County, Tharaka Nithi, Trans Nzoia, Turkana, Uasin Gishu, Vihiga, Wajir, West Pokot",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
),
),
],
),
)
: ListView.builder(
itemCount: driverList.length,
itemBuilder: (context, index) {
final Hospitals hospitals = driverList[index];
final String hospitalLocaiton =
hospitals.location;
final String hospitalPhone = hospitals.phone;
final String hospitalName = hospitals.name;
positiveCount = hospitals.positiveCount;
negativeCount = hospitals.negativeCount;
final int setpercentage =
calculatePositivePercentage(
positiveCount, negativeCount);
buttonControls(driverList.length);
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 0,
child: ExpansionTile(
title: Text(
hospitalName.toUpperCase(),
style: GoogleFonts.lexendMega(),
textAlign: TextAlign.center,
),
children: [
Column(
children: [
Container(
child: (hospitalPhone
.isNotEmpty)
? ElevatedButton(
onPressed: () {
Clipboard.setData(
ClipboardData(
text:
hospitalPhone,
),
);
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.green,
content: Text(
"Number Copied",
textAlign:
TextAlign
.center,
),
),
);
},
child: Text(
hospitalPhone,
textAlign:
TextAlign.center,
style: GoogleFonts
.lexendMega(
fontSize: 13),
),
style: ElevatedButton
.styleFrom(
elevation: 0,
),
)
: const Text(""),
),
const SizedBox(
height: 5,
),
hospitalLocaiton.isNotEmpty
? Container(
padding:
const EdgeInsets.all(
8),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
),
borderRadius:
BorderRadius
.circular(10),
),
child: Text(
hospitalLocaiton,
textAlign:
TextAlign.center,
style: GoogleFonts
.lexendMega(
fontSize: 12,
),
),
)
: Text(
hospitalLocaiton,
textAlign:
TextAlign.center,
style: GoogleFonts
.lexendMega(
fontSize: 12,
),
),
const SizedBox(
height: 10,
),
Text(
"$setpercentage% (percent) of voters say this hospital administer vaccines.",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
fontSize: 12,
color: Colors.deepPurple[400],
),
),
const SizedBox(
height: 10,
),
const Divider(
// thickness: 1,
indent: 20,
endIndent: 20,
color: Colors.black87,
),
const SizedBox(
height: 10,
),
Text(
"Does this Hospital administer Vaccines?\n(To help the public, please vote only if you know.)",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceEvenly,
children: [
ElevatedButton(
onPressed:
buttonPressed[index]
? () {
positiveIncrement(
hospitalName,
index);
buttonPressed[
index] =
false;
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.redAccent,
content:
Text(
"Voted",
textAlign:
TextAlign.center,
),
),
);
}
: null,
child: Text(
"Yes",
style: GoogleFonts
.lexendMega(),
),
style: ElevatedButton
.styleFrom(
primary:
Colour("#87D68D"),
),
),
ElevatedButton(
onPressed:
buttonPressed[index]
? () {
negativeIncrement(
hospitalName,
index);
buttonPressed[
index] =
false;
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.redAccent,
content:
Text(
"Voted",
textAlign:
TextAlign.center,
),
),
);
}
: null,
child: Text(
"No",
style: GoogleFonts
.lexendMega(),
),
style: ElevatedButton
.styleFrom(
primary:
Colour("#E3655B"),
),
),
],
),
const SizedBox(
height: 10,
),
Text(
"1 - To vote, tap once\n2 - To Undo vote, tap and hold",
style:
GoogleFonts.lexendMega(
fontSize: 12,
),
textAlign: TextAlign.start,
),
const SizedBox(
height: 10,
),
],
),
],
),
],
),
),
);
},
),
),
),
// SizedBox(height: 40),
],
),
),
],
),
),
),
);
}
}
class Hospitals {
final String name;
final String phone;
final String location;
// final String county;
final int positiveCount;
final int negativeCount;
// final int intPercentage;
// final int totalVotes;
Hospitals({
required this.name,
required this.phone,
required this.location,
// required this.county,
required this.positiveCount,
required this.negativeCount,
// required this.intPercentage,
// required this.totalVotes,
});
static Hospitals fromJson(Map<String, dynamic> json) {
return Hospitals(
name: json['HospitalName'],
phone: json['HospitalPhone'],
// county: json['county'],
location: json['HospitalAddres'],
positiveCount: json['poitiveCount'],
negativeCount: json['negativeCount'],
// intPercentage: json['intPercentage'],
// totalVotes: json['totalVotes']
);
}
}
I did that this way: use the provider to set value, make boolean value
late bool isMyButtonEnabled;
//in initState
setState(() {
isMyButtonEnabled=
myProvider.checkIfButtonShouldBeEnabled(widget.Id);
}
//in build
ElevatedButton(
child: Text('SUBMIT'),
onPressed: !isMyButtonEnabled
? null
: () async => {
//some code
}
this way your boolean will be saved and available everywhere in the app using the Provider package (there are other even more advanced analogs of Provider there that can be used as well)
I have two files...Workout.dart and Submit.dart. In Workout.dart I have variables: name, sets, rep, pmg, and smg. The use will input things for the variables and then once they click submit, a new page will open displaying the data. However, I don't know how to carry over that data. I'm new to Flutter and Dart, Please help!
Workout.dart
import 'package:flutter/material.dart';
import 'package:gyminprogress/Submit.dart';
class This extends StatefulWidget{
#override
Workout createState() => Workout();
}
class Workout extends State<This> {
String name , sets , rep , pmg , smg ;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
appBar: AppBar(
title: Text('Create Workouts'),
centerTitle: true,
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: 'Exercise Name'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
name = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(
hintText: 'Primary Muscle Group'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
pmg = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(
hintText: 'Secondary Muscle Group'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
smg = value;
});
},
),SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(
hintText: 'Reps'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
rep = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(
hintText: 'Sets'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
sets = value;
});
},
),
Expanded(
child: Container(
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.cyan[200],
padding: EdgeInsets.symmetric(
horizontal: 80.0,
vertical: 20.0
,),
child: Text('Submit',style: TextStyle(
color: Colors.black,fontWeight: FontWeight.w200
),) ,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Submit (
)),
);
},
),
]
),]),)
)
]
)
),
),
);
}
}
Submit.dart
import 'package:flutter/material.dart';
import 'package:gyminprogress/Workout.dart';
class Submit extends StatefulWidget{
#override
Enter createState() => Enter();
}
class Enter extends State<Submit> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
appBar: AppBar(
title: Text('Create Workouts'),
centerTitle: true,
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text('Exercise Name : ${Workout.name}',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
Text('Primary Muscle Group : ${Workout.pmg} ',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
Text('Secondary Muscle Group : ${Workout.smg} ',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
Text('Reps : ${Workout.rep}',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
Text('Sets : ${Workout.sets}',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
]
)
)
)
);
}
}
To pass data from one widget to another you have to do two things,
Create a constructor of widget having data which it will accept,
Pass that data while calling it from another widget.
here is the code which solves your problem:
workout.dart
import "package:flutter/material.dart";
import './submit.dart';
class Workout extends StatefulWidget {
#override
_WorkoutState createState() => _WorkoutState();
}
class _WorkoutState extends State<Workout> {
String name, sets, rep, pmg, smg;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: (context) => Scaffold(
appBar: AppBar(
title: Text('Create Workouts'),
centerTitle: true,
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Scaffold(
body: Column(children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'Exercise Name'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
name = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration:
InputDecoration(hintText: 'Primary Muscle Group'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
pmg = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration:
InputDecoration(hintText: 'Secondary Muscle Group'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
smg = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(hintText: 'Reps'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
rep = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(hintText: 'Sets'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
sets = value;
});
},
),
Expanded(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.cyan[200],
padding: EdgeInsets.symmetric(
horizontal: 80.0,
vertical: 20.0,
),
child: Text(
'Submit',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600),
),
onPressed: () {
//String name, sets, rep, pmg, smg;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Submit(
name: name,
sets: sets,
rep: rep,
pmg: pmg,
smg: smg,
),
),
);
},
),
]),
]),
))
]))),
),
),
),
);
}
}
submit.dart
import "package:flutter/material.dart";
class Submit extends StatelessWidget {
final String name, sets, rep, pmg, smg;
const Submit({
Key key,
this.name = "",
this.sets = "",
this.rep = "",
this.pmg = "",
this.smg = "",
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
appBar: AppBar(
title: Text('Create Workouts'),
centerTitle: true,
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(children: <Widget>[
Text(
'Exercise Name : ${name}',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
Text(
'Primary Muscle Group : ${pmg} ',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
Text(
'Secondary Muscle Group : ${smg} ',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
Text(
'Reps : ${rep}',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
Text(
'Sets : ${sets}',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
]))));
}
}
Output:
New Updated code
Output:
You can pass data in the navigator.
class Workout extends ....> {
String name;
Person(this.name);
}
// Navigate to second screen with data
Navigator.push(context, new MaterialPageRoute(builder: (context) => new SecondScreenWithData(person: new Person("Vishal"))));
Then in the second screen
class SecondScreenWithData extends StatelessWidget {
// Declare a field that holds the Person data
final Person person;
// In the constructor, require a Person
SecondScreenWithData({Key key, #required this.person}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Second Screen With Data"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Display passed data from first screen
Text("name: ${person.name}"),
RaisedButton(
child: Text("Back to previous screen"),
onPressed: () {
// Navigate back to first screen when tapped!
Navigator.pop(context);
}
),
],
)
),
);
}