Basically, what I'm trying to do in my app is to have a CheckBox List Tile and the selected list tiles pass through a button to next screen in a new list just for confirmation of what the user has selected and then send the data to backend. But don't know how to pass all the values that I display in a ListTile such as the first name, last name, id etc., I can pass only one of them.
Can somebody help me with this?
Code below for reference
class AthleteScreen extends StatefulWidget {
const AthleteScreen({Key? key}) : super(key: key);
@override
State<AthleteScreen> createState() => _AthleteScreenState();
}
class _AthleteScreenState extends State<AthleteScreen> {
TextEditingController controller = TextEditingController();
Future<List<Athlete>>? futureAthletebyTeamKey;
final List<Athlete> _athlete = [];
var selectedAthlete = [];
int numberOfChecks = 0;
@override
void initState() {
super.initState();
futureAthletebyTeamKey = getAthletesByTeamKey();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0Xfff7f7f5),
body: Stack(
children: [
SingleChildScrollView(
child: Column(children: [
const SizedBox(
height: 10,
),
FutureBuilder<List<Athlete>>(
future: futureAthletebyTeamKey,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
List<Athlete> _athlete = snapshot.data;
ListView.builder(
shrinkWrap: true,
cacheExtent: 34,
primary: true,
physics: const ClampingScrollPhysics(),
itemCount: _athlete.length,
itemBuilder: (BuildContext context, int index) {
return CheckboxListTile(
title:Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'ID: ${_athlete[index].id}',
style: const TextStyle(
color: Colors.blue,
fontSize: 14),
),
],
),
Row(
children: [
Flexible(
child: Text(
'${_athlete[index].lastName} ${_athlete[index].firstName}',
),
],
),
Row(
children: [
Flexible(
child: Text(
'(${_athlete[index].fatherName})',
),
Text(
'Π: ${_athlete[index].currentMonthPresences}',
],
),
],
),
dense: true,
value: selectedAthlete
.contains(_athlete[index].id),
onChanged: (val) {
setState(() {
if (selectedAthlete
.contains(_athlete[index].id)) {
selectedAthlete
.remove(_athlete[index].id);
numberOfChecks--;
} else {
selectedAthlete.add(_athlete[index].id);
numberOfChecks++;
}
}
);
print(selectedAthlete);
});
});
} else if (snapshot.hasError) {
logger.e('${snapshot.error}');
}
return const Center(
heightFactor: 20,
child: CircularProgressIndicator.adaptive(),
);
},
),
]),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
height: 60,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
disabledBackgroundColor: Colors.grey),
onPressed: numberOfChecks == 0
? null
: (() async {
Navigator.of(context).pushNamed(
SelectedAthletes.routeName,
arguments: selectedAthlete);
}),
child: Column(
children: [
const Text(
'NEXT',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 18),
),
Text(
'($numberOfChecks selected athletes)',
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 14),
)
],
),
),
),
),
and the next screen where I want to display selected List Tiles
class SelectedAthletes extends StatefulWidget {
const SelectedAthletes({
Key? key}) : super(key: key);
static const routeName = '/selectedAthletes';
@override
State<SelectedAthletes> createState() => _SelectedAthletesState();
}
class _SelectedAthletesState extends State<SelectedAthletes> {
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as List<Athlete>;
return Scaffold(
backgroundColor: const Color(0Xfff7f7f5),
body: SingleChildScrollView(
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ListView.builder(
shrinkWrap: true,
cacheExtent: 34,
primary: true,
physics: const ClampingScrollPhysics(),
itemCount: args!.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'ID: ${args[index].id}',
style: const TextStyle(
color: Colors.blue, fontSize: 14),
),
],
),
],
));
},
)
],
),
));
}
Here I can display only the id but I want to display and the rest values in ListTile
SOLVED
and also I don't know what type goes after as in line
final args = ModalRoute.of(context)!.settings.arguments as ??? ;
I put as Athlete that I have on first screen but throws errors
Try cast like this:
final args = ModalRoute.of(context)!.settings.arguments as List<Athlete>;
also you are using your args wrong, please change this line too :
Text(
ID: '${args[index].id}', // change this line
style: const TextStyle(color: Colors.blue, fontSize: 14),
)