如何在 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,
  );
}