如何在 flutter 上设计这个?
How to design this on flutter?
我很困惑是否有任何小部件或任何包可以轻松地用 Flutter 实现这样的东西。选择一个框后,它会在角上打勾,并且只能从多个框中选择一个。
好吧,这里我有一个表格给你,这并不难,只需要一个 ListView 来显示日期(我把一些放在那里作为例子),然后使用 for 循环进行一些验证以将其更改为选中状态。
关于设计已经晚了,因为它需要一个 Stack 放在检查图标的顶部,然后有一些边距和尺寸是 (如果你愿意,可以在每个容器中放置背景颜色,以便你更好地看到它们并自行更改措施)。 FittedBox 仅在此处使用,以便“Mon”的文本适合大小。
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,
);
}
我很困惑是否有任何小部件或任何包可以轻松地用 Flutter 实现这样的东西。选择一个框后,它会在角上打勾,并且只能从多个框中选择一个。
好吧,这里我有一个表格给你,这并不难,只需要一个 ListView 来显示日期(我把一些放在那里作为例子),然后使用 for 循环进行一些验证以将其更改为选中状态。
关于设计已经晚了,因为它需要一个 Stack 放在检查图标的顶部,然后有一些边距和尺寸是 (如果你愿意,可以在每个容器中放置背景颜色,以便你更好地看到它们并自行更改措施)。 FittedBox 仅在此处使用,以便“Mon”的文本适合大小。
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,
);
}