问题
Hi The problem is I have multiple groups of RadioButtons hence can't figure out how onChanged method will work for each group. I have a list of students and want to make a widget where a teacher can mark attendance of students by clicking on one of the Radio Buttons( present,absent,holiday,half day etc.) Here is the implementation
@override
Widget build(BuildContext context) {
print('number students ${studentList.students.length.toString}');
return ListView.builder(
itemCount: studentList.students.length,
itemBuilder: (context, index) {
var gp = studentList.students[index].id;
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 10,
child: ListTile(
title: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
studentList.students[index].name,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
),
leading: CircleAvatar(
radius: 30,
backgroundImage: NetworkImage(
studentList.students[index].details['photo'])),
trailing: Column(
children: <Widget>[],
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Phone: ' +
studentList.students[index].details['phone']),
Text('Batches:'),
Container(
width: MediaQuery.of(context).size.width,
height: 50,
child: ListView.builder(
itemCount: studentList.students[index].batches.length,
itemBuilder: (context, batchIndex) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(studentList
.students[index].batches[batchIndex].name),
],
);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Column(
children: <Widget>[
Radio(
groupValue: gp,
value: 0,
onChanged: (int e) {
print(e);
print(gp);
updateSelectedAttendance(gp, e);
},
),
Text('P')
],
),
Column(
children: <Widget>[
Radio(
groupValue: gp,
onChanged: (int e) {
print(e);
print(gp);
updateSelectedAttendance(gp, e);
},
value: 1,
),
Text('Ab')
],
),
Column(
children: <Widget>[
Radio(
groupValue: gp,
onChanged: (int e) {
print(e);
print(gp);
updateSelectedAttendance(gp, e);
},
value: 2,
),
Text('Hd')
],
),
Column(
children: <Widget>[
Radio(
groupValue: gp,
onChanged: (int e) {
print(e);
print(gp);
updateSelectedAttendance(gp, e);
},
value: 3,
),
Text('H')
],
)
],
),
)
],
),
),
),
);
});
}
updateSelectedAttendance(int gp, int e) {
setState(() {
gp = e;
print('gp ${gp.toString()} -- e ${e.toString()}');
});
}
Here because there would be multiple students , hence there would be multiple groups of Radio Buttons so I have assigned each group a groupValue of id of the individual student. And because there are 4 radio buttons for each student (present,absent,holiday,halfday), I have assigned values of 0,1,2,3. And in onChanged method I am equating gp=value; But it is not behaving the way I want it to behave.
回答1:
//For the deom purpose I'm using Map List...
//Replace the above with your custom model
List<Map> studentList=[];
//Create attendance list to hold attendance
Map<String,String> attendance={};
List<String> labels=['P','Ab','Hd','H'];
@override
void initState() {
super.initState();
getData();
}
getData(){
//Use your own implementation to get students data
//For deom I'm using offline data
studentList.add({
'id':'ID1',
'name':'Naveen Avidi',
'details':'A Programmer'
//other fields...
});
attendance['ID1']='P';
//or null if emtpy
studentList.add({
'id':'ID2',
'name':'Ram',
'details':'An Engineer'
//other fields...
});
attendance['ID2']='Ab';
//or null if emtpy
studentList.add({
'id':'ID3',
'name':'Satish',
'details':'A Developer'
//other fields...
});
attendance['ID3']='Hd';
//or null if emtpy
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:AppBar(
title:Text('Title')),
body: Container(
color:Colors.white,
child: ListView.builder(
itemCount: studentList.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
color:Colors.cyan,
elevation: 10,
child: ListTile(
title: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
studentList[index]['name'],
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold,color:Colors.black),
),
),
leading: CircleAvatar(
radius: 30,
//no pic available
),
trailing: Column(
children: <Widget>[],
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Phone: ' +
studentList[index]['details'],
style:TextStyle(color:Colors.black)),
Text('Batches:',style:TextStyle(color:Colors.black)),
// Container(
// width: MediaQuery.of(context).size.width,
// height: 50,
// child: ListView.builder(
// itemCount: studentList.students[index].batches.length,
// itemBuilder: (context, batchIndex) {
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// Text(studentList
// .students[index].batches[batchIndex].name),
// ],
// );
// },
// ),
// ),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: labels.map((s){
return Column(
children: <Widget>[
Radio(
groupValue: attendance[studentList[index]['id']],
value: s,
onChanged: (newValue) {
setState((){
attendance[studentList[index]['id']]=newValue;
});
},
),
Text(s,style:TextStyle(color:Colors.black))
],
);
}).toList(),
),
)
],
),
),
),
);
})
),
);
}
来源:https://stackoverflow.com/questions/60053914/flutter-onchanged-behaviour-in-radios-with-multiple-groups-not-working-as-expect