I am confused on if there is any widget or any package to make it easy to implement something like this with Flutter. Once a box is selected, it puts a check on the corner, and only one box can be selected out of the many.
CodePudding user response:
Well, here I have a form for you, it is not difficult, only a ListView is needed to show the dates (I put some there as an example), then some validation with a for cycle to change it to selected.
Already later with respect to the design, because it takes a Stack to put on top of the icon of check, then with some margins and measures are (if you like, in each container put background colors so that you see them better and change yourself the measures). The FittedBox is only used here so that the text of "Mon" fits the size.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Material App',
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final List<Date> dates = [
Date("Su", "13", false),
Date("Mon", "14", false),
Date("Tu", "15", false),
Date("We", "16", false),
Date("Th", "17", false),
Date("Sa", "18", false),
];
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Container(
height: 100,
padding: const EdgeInsets.only(left: 20),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: dates.length,
itemBuilder: (context, index) => GestureDetector(
onTap: () {
for (int i = 0; i < dates.length; i ) {
if (i == index) {
dates[i].isSelected = true;
} else {
dates[i].isSelected = false;
}
}
setState(() {});
},
child: DateBox(
date: dates[index],
),
),
),
),
),
);
}
}
class DateBox extends StatelessWidget {
const DateBox({
Key? key,
required this.date,
}) : super(key: key);
final Date date;
@override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.center,
children: [
Container(
width: 55,
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 25,
),
margin: const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: const BorderRadius.all(
Radius.circular(18),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
FittedBox(
fit: BoxFit.fitWidth,
child: Text(
date.name,
style: TextStyle(
color: Colors.grey[400],
),
),
),
const SizedBox(
height: 5,
),
Text(
date.number,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
],
),
),
if (date.isSelected)
const Positioned(
right: 0,
top: 5,
child: Material(
color: Colors.transparent,
shape: CircleBorder(
side: BorderSide(
color: Colors.white,
width: 2,
),
),
child: Icon(
Icons.check_circle,
size: 20,
color: Colors.indigoAccent,
),
),
),
],
);
}
}
class Date {
String name;
String number;
bool isSelected;
Date(
this.name,
this.number,
this.isSelected,
);
}