我有这个设计,是我在Flutter度上创造的:

enter image description here

到目前为止,我做到了以下几点:

enter image description here

我将向您提供我的代码,并对其进行解释,最后我将try 解释我遇到的错误.首先是我的代码:

class CheckoutPage extends StatefulWidget {
  const CheckoutPage({super.key});

  @override
  State<CheckoutPage> createState() => _CheckoutPageState();
}

class _CheckoutPageState extends State<CheckoutPage>
    with TickerProviderStateMixin {
  Map<String, bool> isActive = {
    'Quantity': true,
    'Payment': false,
    'Review': false,
  };
  Map<String, bool> isDone = {
    'Quantity': false,
    'Payment': false,
    'Review': false,
  };
  @override
  Widget build(BuildContext context) {
    order = ModalRoute.of(context)!.settings.arguments as Order;
    final PageController pageViewController = PageController();
    final double height = MediaQuery.of(context).size.height;
    final GlobalKey<FormState> formKey = GlobalKey<FormState>();
    final TextEditingController nameController = TextEditingController();
    final TextEditingController phoneNumberController = TextEditingController();
    final TextEditingController addressController = TextEditingController();

    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: Stack(
        children: [
          Column(
            children: [
              SizedBox(
                height: height * 0.16,
                child: PageViewIndicator(isActive: isActive, isDone: isDone),
              ),
              SizedBox(
                height: height * 0.84,
                child: Padding(
                  padding: const EdgeInsets.symmetric(
                    horizontal: 8,
                    vertical: 18,
                  ),
                  child: PageView(
                    controller: pageViewController,
                    children: [
                      QuantityStepWidget(
                        formKey: formKey,
                        addressController: addressController,
                        nameController: nameController,
                        phoneNumberController: phoneNumberController,
                      ),
                      const PaymentStepWidget(),
                      const ReviewStepWidget(),
                    ],
                  ),
                ),
              ),
            ],
          ),
          const BackButtonWidget(),
        ],
      ),
    );
  }
}

这个代码主要由Scaffold组成,它的子代是Stack,它在Column的点击上堆叠了一个后退按钮(BackButton).该柱具有两个容器SizedBox;第一个容器占据屏幕高度的16%,第二个容器占据84%,总计为Scaffold%.在第一个SizedBox中,我定义了一个PageViewIndicator小部件,它是一个Container,其中包含一个Row,其中包含3个HeadingPageViewItemWidget,如下所示:


class PageViewIndicator extends StatelessWidget {
  final Map<String, bool> isActive;
  final Map<String, bool> isDone;
  const PageViewIndicator({
    super.key,
    required this.isActive,
    required this.isDone,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border(
          bottom: BorderSide(color: AppColors.borderColor),
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.only(left: 8.0, right: 8.0, bottom: 20),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            HeadingPageViewItemWidget(
              number: '1',
              title: 'Quantity',
              isActive: isActive['Quantity']!,
              isDone: isDone['Quantity']!,
            ),
            HeadingPageViewItemWidget(
              number: '2',
              title: 'Payment',
              isActive: isActive['Payment']!,
              isDone: isDone['Payment']!,
            ),
            HeadingPageViewItemWidget(
              number: '3',
              title: 'Review',
              isActive: isActive['Review']!,
              isDone: isDone['Review']!,
            ),
          ],
        ),
      ),
    );
  }
}

HeadingPageViewItemWidget是另一个包含CircleAvatarText小部件的Row,如下所示:


class HeadingPageViewItemWidget extends StatelessWidget {
  final String number;
  final String title;
  final bool isDone;
  final bool isActive;
  const HeadingPageViewItemWidget({
    Key? key,
    required this.number,
    required this.title,
    this.isDone = false,
    this.isActive = false,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 100,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          CircleAvatar(
            backgroundColor: _getColor(isDone: isDone, isActive: isActive),
            radius: 15,
            child: _getIconOrNumber(isDone),
          ),
          SizedBox(
            width: 60,
            child: Text(title, style: kCaption0),
          ),
        ],
      ),
    );
  }
}

在第二个SizedBox中,我定义了一个PageView,它有3个子元素,QuantityStepWidgetPaymentStepWidgetReviewStepWidget,最后两个暂时只是PlaceHolder.QuantityStepWidget的定义如下:


class QuantityStepWidget extends StatelessWidget {
  final GlobalKey<FormState> formKey;
  final TextEditingController nameController;
  final TextEditingController phoneNumberController;
  final TextEditingController addressController;
  const QuantityStepWidget(
      {super.key,
      required this.formKey,
      required this.nameController,
      required this.phoneNumberController,
      required this.addressController});

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: SizedBox(
        height: MediaQuery.of(context).size.height * 0.8,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Flexible(
              fit: FlexFit.loose,
              child: SizedBox(
                  height: MediaQuery.of(context).size.height * 0.05,
                  child: const TitleWidget(title: 'Quantity')),
            ),
            Flexible(
              flex: 3,
              fit: FlexFit.loose,
              child: SizedBox(
                height: MediaQuery.of(context).size.height * 0.35,
                width: double.infinity,
                child: MedicationCheckoutQuantityWidget(order: order),
              ),
            ),
            Flexible(
              flex: 3,
              fit: FlexFit.loose,
              child: SizedBox(
                height: MediaQuery.of(context).size.height * 0.4,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      'Confirm your information',
                      style: kH3TitleStyle,
                    ),
                    const SizedBox(height: 10),
                    Flexible(
                      fit: FlexFit.loose,
                      child: SizedBox(
                        height: 200,
                        child: Form(
                          key: formKey,
                          child: Column(
                            children: [
                              Flexible(
                                flex: 1,
                                fit: FlexFit.loose,
                                child:
                                    TextFormFieldUserInformationsConfirmationWidget(
                                  type: FormType.name,
                                  controller: nameController,
                                ),
                              ),
                              Flexible(
                                flex: 1,
                                fit: FlexFit.loose,
                                child:
                                    TextFormFieldUserInformationsConfirmationWidget(
                                  type: FormType.phoneNumber,
                                  controller: phoneNumberController,
                                ),
                              ),
                              Flexible(
                                flex: 1,
                                fit: FlexFit.loose,
                                child:
                                    TextFormFieldUserInformationsConfirmationWidget(
                                  type: FormType.address,
                                  controller: addressController,
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                    const SizedBox(height: 20),
                    ButtonWidget(
                        onPressed: () {
                          print('lol');
                          if (formKey.currentState!.validate()) {
                            print(nameController.text);
                            print(phoneNumberController.text);
                            print(addressController.text);
                          }
                        },
                        text: 'Confirm'),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

它由一个SingleChildScrollView组成,里面有一个Column,其中包含三个Flexible个小部件;第一个是"数量"标题,第二个是药物名称和数量的两张卡片,第三个是表格.

我想要的是当键盘被触发时使窗体上升,但它不想这样做,它所做的只是显示键盘,然后立即关闭它,它没有时间添加文本,一旦键盘打开它关闭

推荐答案

将这两个放在您的构建方法之外:

final double height = MediaQuery.of(context).size.height;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();

欲了解更多信息,请访问此帖子:StackOverflow answer

Flutter相关问答推荐

未处理异常:字符串类型不是值类型子类型的子类型'

无法在主屏幕视图中设置当前日期容器'

为什么Flutter InAppWebView中的DatePicker看起来很旧?

Android上火焰瓷砖之间的线条飘动

如何在Flutter 中共享选定文本

在选项卡栏视图中搜索和筛选不起作用

如何在Flutter 中创造以下效果

如何将WebViewWidget和WillPopScope结合起来

在Flutter 中创建自定义形状

播放特定持续时间Flutter 的音频

如何在 Flutter 中创建具有渐变背景色的自定义 Snackbar?

尽管海拔设置为 0,如何删除 appBar 下的下划线

你如何在 Flutter 中组合两个数组?

状况不佳 - Cubit

如何在 flutter 的alert 对话框中实现进度指示器?

如何在 Flutter 执行通知时运行后台代码?

在 flutter 中自定义 agora 视频通话 UI

如何获取 android 和 Ios (flutter) 的 CircularProgress 指示器?

如何让多个图标转到不同的网址

如何在 SingleChildScrollView 小部件中管理自定义小部件状态