I have this project am working on, but there is this particular point I can't get pass through. I want to control the amount of list to be selected by the user. I want the user to select only two from the list or 3 from the list. And also, I want to validate that the user selected the amount I want the user to select.
Please help me out. This is my code so far.
class _LibraChoosePayState extends State<LibraChoosePay> {
List<int> selectedService = [];
List<dynamic> services = [
[ Plans.electrician, Plans.electrician, "Electrician", "For electrical repairs and works. Both for offices and homes. Anywhere.", 0],
[ Plans.mechanic, Plans.mechanic, "Electrician", "For electrical repairs and works. Both for offices and homes. Anywhere.", 0],
[ Plans.electrician, Plans.electrician, "Electrician", "For electrical repairs and works. Both for offices and homes. Anywhere.", 1],
[ Plans.electrician, Plans.electrician, "Electrician", "For electrical repairs and works. Both for offices and homes. Anywhere.", 0],
];
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.backgroundLightMode,
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: SingleChildScrollView(
child: SafeArea(
child: Container(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
IconButton(
onPressed:() {
Navigator.popAndPushNamed(context, SelectPlan.idScreen);
},
icon: AppAllIcons.arrowDown
),
const SizedBox(width: 60,),
const Text(
"Select and Subscribe",
style: AppTextStyle.headerTextDarkStyle,
)
],
),
const SizedBox(height: 20,),
SizedBox(
height: 500,
child: ListView.builder(
itemCount: services.length,
itemBuilder: ((context, index) {
return GestureDetector(
onTap: () {
setState(() {
//selectedService = index;
if(selectedService.contains(index)) {
selectedService.remove(index);
} else{
selectedService.add(index);
}
});
},
child: AnimatedContainer(
margin: const EdgeInsets.all(10),
duration: const Duration(milliseconds: 800),
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(15)),
color: Colors.white,
border: Border.all(
color: selectedService.contains(index) ? Colors.blue : Colors.white.withOpacity(0),
width: 2
),
boxShadow: [
selectedService.contains(index) ?
BoxShadow(
color: Colors.blue.shade100,
offset: const Offset(0, 3),
blurRadius: 10
) : BoxShadow(
color: Colors.grey.shade100,
offset: const Offset(0, 3),
blurRadius: 10
)
]
),
child: Row(
children: [
selectedService.contains(index) ? Image.asset(services[index][0], width: 50,) :
Image.asset(services[index][1], width: 50,),
const SizedBox(width: 30,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(services[index][2], style: TextStyle(
color: Colors.grey.shade800,
fontSize: 16,
fontWeight: FontWeight.bold
),),
Text(services[index][3], style: TextStyle(
color: Colors.grey.shade600,
fontSize: 14,
),)
],
),
),
Icon(Icons.check_circle, color: selectedService.contains(index) ? Colors.blue : Colors.white,)
],
),
),
);
})
),
),
const SizedBox(height: 20,),
]
),
)
,
),
),
)
);
}
}
It allows the user to select everything in the list.
CodePudding user response:
Why don't you just check the selectedServices.length?
onTap: () {
// user is deselecting a service, OK
if (selectedServices.contains(index)) {
setState(() {
selectedServices.remove(index);
});
}
// user is selecting a service
else {
// check of limit
if (selectedServices.length == ALLOWED_LIMIT) {
// tell user to only select at most ALLOWED_LIMIT services.
}
// user hasn't select allowed services limit
else {
setState(() {
selectedServices.add(index);
});
}
}
}
CodePudding user response:
Only need to change the code is onTap
onTap: () {
int maxSelectCount = 2; // your count
setState(() {
//selectedService = index;
if (selectedService.contains(index)) {
selectedService.remove(index);
} else {
// Condition for selection
if (selectedService.length < maxSelectCount) {
selectedService.add(index);
} else {
///Message you could not select more than [maxSelectCount]
}
}
});
},
for validation you can set on payment button click
if (selectedService.isEmpty)
{
///Message: You should select at least 1 service to proceed further
}else
{
///Payment code or any
}