List of Radio button in flutter - flutter

For my project i display a list of football game with the choice for the user of (3 radios buttons with value "1" "N" or "2").
Example : i need list of football game like that :
Arsenal-Tottenham 1 N 2
Liverpool-Manchester 1 N 2
PSG-Dortmund 1 N 2
1 N 2 are radio button, each member can so choose between the 3 value for each game. The problem is i Don't see how identify each radio button for be unique. I need at the end display a validation button which allows the members to save the result of each choice. For make simple if you choose 1 for the 3 games i need to pass "111" to an external server by php api
Here is my code for display the form with radio button : Note that the games are from a list (values.map), so number of games can vary
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:async';
// Create a Form widget.
class Affiche_grille extends StatefulWidget {
#override
_Affiche_grille_State createState() {
return _Affiche_grille_State();
}
}
// Create a corresponding State class.
// This class holds data related to the form.
class _Affiche_grille_State extends State<Affiche_grille> {
#override
final _formKey = GlobalKey<FormState>();
Future <List<Match>> Grille_display() async {
// SERVER LOGIN API URL
var url = 'http://www.axis-medias.fr/game_app/display_grid.php';
// Store all data with Param Name.
var data = {'id_grille': 1};
// Starting Web API Call.
var response = await http.post(url, body: json.encode(data));
// Getting Server response into variable.
var jsondata = json.decode(response.body);
List<Match> Matchs = [];
for (var u in jsondata) {
Match match = Match(u["equipe1"],u["equipe2"],u["type_prono"]);
Matchs.add(match);
}
return Matchs;
}
List<String> radioValues = [];
#override
Widget build(BuildContext context) {
final appTitle = 'MONEYFREE';
return MaterialApp(
title: appTitle,
home: Scaffold(
appBar: AppBar(
title: Text(appTitle),
),
body: Container(
child:
FutureBuilder(
future: Grille_display(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container (
child: Center(
child: Text("Loading...")
)
);
}
else {
List<Match> values = snapshot.data;
values.forEach((m){
radioValues.add("N");
//like N or something
});
print('valeur radio après initialisation');
print(radioValues);
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
DataTable(
columnSpacing: 20,
columns: [
DataColumn(
label: Text("Libelle Match"),
numeric: false,
tooltip: "",
),
DataColumn(
label: Text("1"),
numeric: false,
tooltip: "",
),
DataColumn(
label: Text("N"),
numeric: false,
tooltip: "",
),
DataColumn(
label: Text("2"),
numeric: false,
tooltip: "",
),
],
rows:
List.generate(values.length, (index) {
return DataRow(
cells: [
DataCell(
Text(values[index].equipe1.toString() + " - " + values[index].equipe2.toString()),
),
DataCell(
Radio(
value: "1",
groupValue: radioValues[index],
onChanged: (val) {
setState(() {
radioValues[index] = val;
print('Change 1');
print(radioValues);
});
},
),
),
DataCell(
Radio(
value: "N",
groupValue: radioValues[index],
onChanged: (val) {
setState(() {
radioValues[index] = val;
print(radioValues);
});
},
),
),
DataCell(
Radio(
value: "2",
groupValue: radioValues[index],
onChanged: (val) {
setState(() {
radioValues[index] = val;
print(radioValues);
});
},
),
),
]
);
}).toList(),
),
Center(
child: RaisedButton(
color: Colors.green,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(9, 9, 9, 9),
child: Text('VALIDER VOTRE GRILLE'),
onPressed: () {
Valide_grille();
},
),
),
],
)
);
};
},
),
),
),
);
}
Future Valide_grille() async{
// For CircularProgressIndicator.
bool visible = false ;
// Showing CircularProgressIndicator.
setState(() {
visible = true ;
});
// SERVER LOGIN API URL
var url = 'http://www.axis-medias.fr/game_app/valide_grid.php';
// Store all data with Param Name.
var data = jsonEncode(radioValues);
print(radioValues);
// Starting Web API Call.
var response = await http.post(url, body: json.encode(data));
// 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{
// If Email or Password did not Matched.
// 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();
},
),
],
);
},
);
}
}
}
class Match {
final String equipe1;
final String equipe2;
final String typeprono;
const Match(this.equipe1, this.equipe2, this.typeprono);
}

Create a global list
List<String> radioValues = [];
and assign each default value where you are assigning data to radios
values.forEach((m){
radioValues.add(/*assign default values here*/);
//like N or something
});
rows: List.generate(values.length, (index){
return DataRow(
cells: [
DataCell(
Text(values[index].equipe1.toString()+" - "+match.equipe2.toString()),
),
DataCell(
Radio(
value:"1",
groupValue: radioValues[index],
onChanged: (val) {
setState(() {
radioValues[index] = val;
});
},
),
),
DataCell(
Radio(
value:"N",
groupValue: radioValues[index],
onChanged: (val) {
setState(() {
radioValues[index] = val;
});
},
),
),
DataCell(
Radio(
value:"2",
groupValue:radioValues[index],
onChanged: (val) {
setState(() {
radioValues[index] = val;
});
},
),
),
]
);
}).toList(),

If you want to create a list of Radio button use RadioListTile
For details check out this link: https://api.flutter.dev/flutter/material/RadioListTile-class.html
-- i hope this will be helpful for you

You can use Custom Radio group list package available on pub.dev
https://pub.dev/packages/custom_radio_group_list
If you want to Generate a radio button list using a list of string
Just pass list of string like this.
You can set selected item by just passing index of it.
RadioGroup(
radioList: sampleListString,
selectedItem: 1,
onChanged: (value) {
print('Value : ${value}');
},
disabled: true)
If you want to generate a radio button list using any Object.
Just turn that Object to a Map and create a list of Map and key whose data needs to be displayed.
Then use it like below.
RadioGroup(
radioListObject: sampleList,
textParameterName: 'data',
selectedItem: 1,
onChanged: (value) {
print('Value : ${value}');
} )

Related

Flutter/Dart - How can I pass radio button value to a different class in another file?

I need to pass the radio button value stored in variable radioValue from homepage.dart to class DialogFactory in dialogfactory.dart, where I will use it. The current radioValue value should be passed when I press a button which calls function _openDialog(), which is meant to open the alert dialog with the selected style.
======================================
homepage.dart
[...]
class _MyHomePageState extends State<MyHomePage> {
int radioValue = 1;
void _handleRadioValueChange(int value) {
setState(() {
radioValue = value;
});
}
void _openDialog() {
DialogFactory.showAlertDialog(
context,
title: Text('Alert Dialog!!!'),
content: Text(
'THIS IS AN ALERT DIALOG! IT MEANS YOU SHOULD BE IN ALERT STATE, RIGHT?'),
actions: [
DialogAction(
child: Text('YES'),
onPressed: () => print('YES'),
),
DialogAction(
child: Text('NO'),
onPressed: () => print('NO'),
)
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Radio(
value: 0,
groupValue: radioValue,
onChanged: _handleRadioValueChange,
),
new Text('IOS'),
Radio(
value: 1,
groupValue: radioValue,
onChanged: _handleRadioValueChange,
),
new Text('Android'),
RaisedButton(
child: Text('Show Alert'),
color: Colors.purple,
textColor: Colors.white,
onPressed: _openDialog,
),
],
),
),
);
}
}
dialogfactory.dart:
class DialogFactory {
static Future<T> showAlertDialog<T>(BuildContext context,
{Widget title, Widget content, List<DialogAction> actions}) {
IDialog dialogData;
int radioValue = -1;
// HOW TO GET RADIO VALUE?
if (radioValue == 0) {
// ios
dialogData = IosDialog();
} else if (radioValue == 1) {
//android
dialogData = AndroidDialog();
} else {
dialogData = AndroidDialog();
}
return showDialog(
context: context,
builder: (context) => dialogData.create(
context,
title ?? Text('Não informado'),
content ?? Text('Não informado'),
actions ?? [],
),
);
}
}
link to the repository with the code: https://github.com/gicraveiro/FactoryMethod
I passed the radioValue from the homepage.dart into the showAlertDialog.

Create dynamic radio buttons in Flutter

I am trying to create a dynamic form which contains some textbox and radio button. I am using RadioListTile for the same.
In the below code you can see I am using var nameController = TextEditingController(); to get the value of textbox. I am not sure what can be used for RadioListTile.
I am also struggling to show Radio Button Dynamically. I have added full code in the below. How can I get the radio button working and get the value of the selected items, so they can be saved to the database?
class Price extends StatefulWidget {
#override
_PriceState createState() => _PriceState();
}
class FruitsList {
String name;
int index;
FruitsList({this.name, this.index});
}
class _PriceState extends State<Price> {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _scaffoldKey = GlobalKey<ScaffoldState>();
int currentIndex = 0;
String person;
String age;
String job;
// Default Radio Button Item
String radioItem = 'Mango';
// Group Value for Radio Button.
int id = 1;
List<FruitsList> fList = [
FruitsList(
index: 1,
name: "Mango",
),
FruitsList(
index: 2,
name: "Banana",
),
FruitsList(
index: 3,
name: "Apple",
),
FruitsList(
index: 4,
name: "Cherry",
),
];
#override
void initState() {
super.initState();
cards.add(createCard());
}
var nameTECs = <TextEditingController>[];
var ageTECs = <TextEditingController>[];
var jobTECs = <TextEditingController>[];
--- Need to help to add Controller for Radio Button ---
var cards = <Card>[];
Card createCard() {
var nameController = TextEditingController();
var ageController = TextEditingController();
var jobController = TextEditingController();
nameTECs.add(nameController);
ageTECs.add(ageController);
jobTECs.add(jobController);
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Service ${cards.length + 1}'),
TextFormField(
style: TextStyle(color: Colors.blue),
controller: nameController,
decoration: InputDecoration(labelText: 'Name'),
validator: validatetext,
onSaved: (String val) {
person = val;
},
),
TextFormField(
style: TextStyle(color: Colors.blue),
controller: ageController,
decoration: InputDecoration(labelText: 'age'),
validator: validatetext,
onSaved: (String val) {
age = val;
},
),
TextFormField(
style: TextStyle(color: Colors.blue),
controller: jobController,
decoration: InputDecoration(labelText: 'Job'),
validator: validatetext,
onSaved: (String val) {
job = val;
},
),
//Expanded(
// child: Container(
// height: 350.0,
// child:
Row(
children:
fList.map((data) => RadioListTile(
title: Text("${data.name}"),
groupValue: id,
value: data.index,
onChanged: (val) {
setState(() {
radioItem = data.name ;
id = data.index;
});
},
)).toList(),
),
//)),
/* CheckboxListTile(
title: Text("title text"),
value: checkedValue,
onChanged: (newValue) {
setState(() {
checkedValue = newValue;
});
},
//onChanged: (newValue) { ... },
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
), */
SizedBox(height: 10),
],
),
// ),
);
}
void _validateInputs() {
print('button');
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
_onDone();
} else {
}
}
_onDone() {
updateProfile();
List<PersonEntry> entries = [];
for (int i = 0; i < cards.length; i++) {
var name = nameTECs[i].text;
var age = ageTECs[i].text;
var job = jobTECs[i].text;
entries.add(PersonEntry(name, age, job));
}
}
///////// Save to DB ////////////////////
Future updateProfile() async{
try{
for (int i = 0; i < cards.length; i++) {
var name = nameTECs[i].text;
var age = ageTECs[i].text;
var job = jobTECs[i].text;
Map<String, dynamic> body = {'name': name, 'age': age, 'job' : job };
print(body);
nameTECs[i].clear();
//if(rang == true){
Response response =
await Dio().post("http://192.168.1.102:8080/adddetails.php", data: body);
print(response.statusCode);
if(response.statusCode == 404){
print('404');
}
if(response.statusCode == 200){
nameTECs[i].clear();
}
}
} catch (e) {
print("Exception Caught: $e");
}
}
///////////////////////////////
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: myAppBar(),
endDrawer: myDrawer(),
body: Column(
children: <Widget>[
Expanded(
child:new Form(
key: _formKey,
child: ListView.builder(
itemCount: cards.length,
itemBuilder: (BuildContext context, int index) {
return cards[index];
},
),
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 2.0),
color: Colors.grey,
child:Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Container(
Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
heroTag: "btn1",
child: Icon(Icons.add),
onPressed: () => setState(() => cards.add(createCard())),
backgroundColor: Colors.green,
)
/*RaisedButton(
child: Text('Add new'),
onPressed: () => setState(() => cards.add(createCard())),
),*/
),
Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
heroTag: "btn2",
child: Icon(Icons.remove), onPressed: () => setState(() => cards.removeLast()),
backgroundColor: Colors.red,
)
),
Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
heroTag: "btn3",
child: Icon(Icons.save), onPressed: _validateInputs),
)
],
),
),
],
),
);
}
);
}
}
class PersonEntry {
final String name;
final String age;
final String studyJob;
PersonEntry(this.name, this.age, this.studyJob);
#override
String toString() {
return 'Person: name= $name, age= $age, study job= $studyJob';
}
}
Size get preferredSize => Size.fromHeight(kToolbarHeight);
String validatetext(String value) {
if (value.length < 5)
return 'More than 5 char is required';
else
return null;
}
Update
I want to show Radio buttons that user can select and once user submit the form I can get those value for http request. As you can I have added options to add or remove cards. So, these radio buttons will also generated.
Create field int _selectedRadioIndex
and change code
fList.map((data) => RadioListTile(
title: Text("${data.name}"),
groupValue: id,
value: data.index,
onChanged: (val) {
setState(() {
radioItem = data.name ;
id = data.index;
});
},
)).toList(),
to
fList.map((data) => RadioListTile(
title: Text("${data.name}"),
groupValue: id,
value: data.index,
onChanged: (val) {
setState(() {
radioItem = data.name ;
id = data.index;
_selectedRadioIndex = val;
});
},
)).toList(),
then in code just get it fList.firstWhere((element) => element.index == _selectedRadioIndex)

In Flutter Unable to change the state of DropDown Menu in ListView

I'm trying to change the state of DropDown using setState, value is changing but it is not reflecting on UI, it's only reflecting on the new widget when I'm adding a new Widget.
App Function
Initially, it's a blank screen
When I click on Add it will add dropdown menu & text field
Similarly, we can add many. Those widgets will be added to _mypets list
When I click on save I'm printing an array of lists
How can I change the state?
This is a Stateful Widget
Please help me to resolve this issue
class _MyPetNameState extends State<MyPetName> {
var locationArray = [];
var _myPets = List<Widget>();
String sampleData = 'Hello';
int _index = 1;
var dataForm;
String partnerName;
List<_dropListItem> _weekItems = [
_dropListItem(1, "Pet Type 1"),
_dropListItem(2, "Pet Type 2"),
_dropListItem(3, "Pet Type 3"),
_dropListItem(3, "Pet Type 4"),
];
List<DropdownMenuItem<_dropListItem>> _weekMenuItems;
_dropListItem _selectedWeekItem;
List<DropdownMenuItem<_dropListItem>> buildDropDownMenuItems(List listItems) {
List<DropdownMenuItem<_dropListItem>> items = List();
for (_dropListItem listItem in listItems) {
items.add(
DropdownMenuItem(
child: Text(listItem.name),
value: listItem,
),
);
}
return items;
}
void _addLocation() {
Map<String, String> _formData= {};
int keyValue = _index;
_myPets = List.from(_myPets)
..add(Column(
key: Key("${keyValue}"),
children: <Widget>[
Container(
padding: EdgeInsets.all(20.0),
child: DropdownButton<_dropListItem>(
value: _selectedWeekItem,
items: _weekMenuItems,
onChanged: (value) {
_formData['location'] = value.name;
setState(() {
_weekMenuItems = buildDropDownMenuItems(_weekItems);
_selectedWeekItem = value;
});
}),
),
Container(
child: TextFormField(
initialValue: '',
onChanged: (val) {
_formData['locationType'] = val;
setState(() {
sampleData = val;
});
},
),
),
],
));
setState(() => ++_index);
locationArray.add(_formData);
}
void _sub(int _deleteIndex){
setState(() {
_myPets = List.of(_myPets)..removeAt(_deleteIndex - 1);
--_index;
});
}
#override
void initState() {
// TODO: implement initState
super.initState();
_weekMenuItems = buildDropDownMenuItems(_weekItems);
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
print('');
print(locationArray);
setState(() {
dataForm = [];
});
},
child: Text('Save'),
),
appBar: AppBar(
title: Text('Add your pets'),
actions: <Widget>[
FlatButton(
child: Text('Add'),
onPressed: (){
_addLocation();
},
),
],
),
body: Column(
children: [
Expanded(
child: ListView(
children: _myPets,
),
),
],
),
);
}
}
class _dropListItem {
int value;
String name;
_dropListItem(this.value, this.name);
}
I have made some changes in your code
This may help you
class _MyPetNameState extends State<MyPetName> {
List<dynamic> radioval = [];
setSelectedRadio(int val, int idx) {
setState(() {
radioval[idx]["value"] = val;
});
}
Widget _radioui(int keyValue) {
return Column(
children: <Widget>[
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
Radio(
value: 0,
groupValue: radioval[keyValue]["value"],
activeColor: Colors.green,
onChanged: (val) {
print("Radio $val");
setSelectedRadio(val, keyValue);
},
),
Radio(
value: 1,
groupValue: radioval[keyValue]["value"],
activeColor: Colors.blue,
onChanged: (val) {
print("Radio $val");
setSelectedRadio(val, keyValue);
},
),
],
)
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
radioval.add({"name": "pet1", "value": 0});
});
},
child: Icon(Icons.add),
),
appBar: AppBar(
title: Text('Add your pets'),
),
body: Column(
children: [
Expanded(
child: ListView(
children: [for (int i = 0; i < radioval.length; i++) _radioui(i)],
),
),
],
),
);
}
}

Filed Assertion: line 298 pos 10: 'data != null' : A non-null String must be provided to a Text Widget

I have this challenge. All I want to do is to display the item whose quantity was updated on the data table. I can display the item and the quantity. I can also reset the quantity but when I tried to click Save so it should populate on the datatable and perhaps make update request latter, it displays this error below:
And this is the List of the Items:
THis is the form that allows me update the quantity:
Also Instead of displaying the data in Listile. I want to display the data in ListBody with Divider but I don't know how to do it. All the methods I've tried its throwing and error; the widget.farmerBvn and widget.dc_dcOid, Username can be replaced with this parameters:
farmerBvn=22499183844 dcOid=11, agentName=johndoh
I've tried but I keep getting this error on this and how to change the view from Listile to maybe ListBody where I can display more attributes. Please can anyone help me I am new to flutter.
Here's the code that helps me display the Items on a List:
//List Start Here
child: ListView(
children: eops.map((e) {
return ListTile(
onTap: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20)),
title: Text(e.itemName),
content: TextField(
controller: quantity,
keyboardType:
TextInputType.number,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(
7),
),
labelText:
'Input Quantity Collected',
hintText:
e.quantityAllocated),
),
actions: <Widget>[
FlatButton(
child: Text('Reset'),
onPressed: () {
setState(() {
quantity.text = '';
});
},
),
FlatButton(
child: Text('Save'),
onPressed: () {
bool neww = true;
for (EopLine n
in selectedEops) {
if (n.oid == e.oid) {
setState(() {
n.quantityCollected =
quantity.text;
});
neww = false;
break;
}
}
if (neww == true) {
setState(() {
selectedEops.add(EopLine(
oid: e.oid,
itemName: e.itemName,
quantityCollected: e
.quantityCollected,
createdBy:
e.createdBy,
createdOn:
DateTime.now()
.toString(),
itemType: e.itemType,
measuringUnit:
e.measuringUnit));
});
neww = false;
}
Navigator.pop(context);
},
),
],
);
});
},
leading: (
FittedBox(
fit: BoxFit.contain,
child:Text(e.itemName),
)
),
title: Text('${e.quantityAllocated}'),
trailing: Text('${e.quantityCollected}'),
);
// separatorBuilder:
// (context, index) {
// return Divider();
// };
}).toList(),
),
// ],
// ),
),
//And it ends here
And this is the datatable I want to populate:
//Table starts here
child: DataTable(
columns: [
DataColumn(
label: Text('S/N'),
),
DataColumn(
label: Text('EOP Items'),
),
DataColumn(
label: Text('Qty Collected'),
),
// Lets add one more column to show a delete button
DataColumn(
label: Text('Update'),
)
],
rows: selectedEops
.map(
(eop) => DataRow(
selected: selectedEops.contains(eop),
cells: [
DataCell(
Text('${eop.oid}'),
onTap: () {
print('Selected ${eop.oid}');
},
),
DataCell(
Text(eop.itemName),
onTap: () {
print(
'Selected ${eop.itemName}');
},
),
DataCell(
Text(eop.quantityCollected ?? 0),
onTap: () {
print(
'Selected ${eop.quantityCollected ?? 0}');
},
),
DataCell(
Text(eop.quantityAllocated.toString() ?? 0),
onTap: () {
print(
'Selected ${eop.quantityAllocated.toString() ?? 0}');
},
showEditIcon: true,
),
]),
)
.toList(),
),
),
),
///Table Ends here
In the arrays of products in this eops afer the map function I can see quantityAllocated shows null but other items are showing. any line below the eops.map(e) this quantityallocated and some other show null while the rest is showing its value.
children: eops.map((e)
this is the function that performs the http request:
Future<EopLine> get_farmer_eop() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var userJson = localStorage.getString('loginRes');
user = json.decode(userJson);
print(user['UserName']);
final response = await http.get(
'http://api.ergagro.com:112/GenerateFarmersEop?farmerBvn=${widget.result}&dcOid=${widget.dc_result}&agentName=${user['UserName']}',
headers: _setHeaders());
print('${response.statusCode}popo');
if (response.statusCode == 200 && response.body != null) {
final jsonStatus = jsonDecode(response.body);
maineops = jsonStatus['Eop'];
List<dynamic> EopItems = maineops['EopLines'];
for (var i in EopItems) {
print('${i['Oid'].toString()} eopitemid');
setState(() {
eops.add(EopLine(
oid: i['Oid'],
itemType: i['EopType'].toString(),
itemName: i['ItemName'],
quantityAllocated: i['QuantityAllocated'].toString(),
quantityCollected: i['QuantityCollected'].toString(),
measuringUnit: i['MeasuringUnit'],
));
// r = maineops;
});
}
} else {
Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
backgroundColor: Colors.grey,
),
);
}
throw Exception();
}
_setHeaders() => {
'Content-type': 'application/json',
'Accept': 'application/json',
};

List view radio buton not selecting when selected

When i run the program on a device when i tick 2nd or 3rd term it does not take effect.
I am developing an Electronic student attendance tracking system so i decided to use a radio to track the term and also use check box to track the attendance that is checked if the student is present and unchecked if the student is not present but when i check the term radio it gives the correct output on the console but does not take effect on the physical screen.
import 'package:flutter/material.dart';
import 'package:atttendance_register/dataFiles/pupils.dart';
import 'package:atttendance_register/dataFiles/attendance.dart';
import 'package:intl/intl.dart';
class attendance extends StatefulWidget {
static Future<void> show(BuildContext context) async {
await Navigator.of(context).push(
MaterialPageRoute(builder: (context)=>attendance(),fullscreenDialog: true),
);
}
#override
_attendanceState createState() => _attendanceState();
}
class _attendanceState extends State<attendance> {
// final List<Pupils> pupils =[
// Pupils('John', ' Doe', 'Brad', 'Male', '001', DateTime.now(), '21'),
// Pupils('Jane', ' Doe', 'Mary', 'Female', '002', DateTime.now(), '21'),
// Pupils('Mohamed', ' James', '', 'Male', '003', DateTime.now(), '33'),
// Pupils('Titus', ' Nabieu', 'Jusu', 'Male', '004', DateTime.now(), '21'),
// Pupils('Steven', ' kai', 'Rogers', 'Male', '005', DateTime.now(), '21'),
// Pupils('Josephine', ' Bah', 'Neneh', 'Female', '006', DateTime.now(), '23')
//
// ];
final List<Attendance> attendance =[
Attendance(false,'John Doe Brad',DateTime.now(),0),
Attendance(true,'Jane Doe Mary',DateTime.now(),2),
Attendance(false,'Mohamed James',DateTime.now(),1),
Attendance(false,'Titus Nabieu Jusu',DateTime.now(),2),
Attendance(false,'Steven kai Rogers',DateTime.now(),2),
Attendance(false,'Josephine Bah Neneh',DateTime.now(),1)
];
bool selectedCheck = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Enter Attendance'),
backgroundColor: Colors.blue[900],
),
backgroundColor: Colors.blue[100],
body:Container(
child: ListView.builder(
itemCount:attendance.length,
itemBuilder:(BuildContext context, int index){
int selectedRadio = attendance[index].Term;
bool selectedCheck = attendance[index].attendance;
return Container(
child: Card(
child: Column(
//final pupil =pupils[index];
children: <Widget>[
Text(attendance[index].pupilName),
Text('Select Term'),
Row(
children: <Widget>[
Radio(
value:0,
groupValue: selectedRadio,
activeColor: Colors.blue,
onChanged: (T){
print(T);
setState(() {selectedRadio = T;}
);},
),
new Text(
'1st Term'
),
new Radio(
value: 1,
groupValue: selectedRadio,
activeColor: Colors.blue,
onChanged: (T){
print(T);
setState(() {selectedRadio = T;}
);
},
),
new Text(
'2nd Term'
),
new Radio(
value: 2,
groupValue: selectedRadio,
activeColor: Colors.blue,
onChanged: (T){
print(T);
setState(() {selectedRadio = T;}
);
},
),
new Text(
'3rd Term',
),
],
),
Row(
children: <Widget>[
Checkbox(
value: selectedCheck,
activeColor: Colors.blue,
onChanged: (bool value){
print(value);
setState(() {selectedCheck = value;}
);},
),
new Text(
'Present'
),
],
),
],
),
),
);
} ,),
),
);
}
// Widget pupilsCard(BuildContext context, int index){
// final pupil =pupils[index];
// bool selectedRadio = false;
//
// return Container(
// child: Card(
// child: Column(
// children: <Widget>[
// Text(pupil.FirstName+' '+pupil.OtherName+' '+pupil.LastName),
// Text('Select Term'),
// Row(
// children: <Widget>[
//
//
// ],
// ),
// Checkbox(
// value: selectedRadio,
// activeColor: Colors.blue,
// onChanged: (bool value){
// print(value);
// setState(() {selectedRadio = value;}
// );},
// ),
// new Text(
// 'Present'
//
// ),
// ],
// ),
// ),
// );
// }
}
In the onChanged property of your Radio widgets and your Checkbox widget, you are assigning the user selected value to the variable selectedRadio / selectedCheck and here is the problem, because when the new State is created through setState, the ListView is rebuilding and you are reassigning selectedRadio / selectedCheck the old value of the objects in this lines:
int selectedRadio = attendance[index].Term;
bool selectedCheck = attendance[index].attendance;
So you were not changing the actual value of the objects in the List, but you have too:
onChanged: (T) {
print(T);
setState(() => attendance[index].Term = T);
},
and
onChanged: (value) {
print(value);
setState(() => attendance[index].attendance = value);
},