英文:
What to do when the keyboard is hiding the form?
问题
I see that you're working on a Flutter project and have shared some Dart code for translation. If you have specific parts of the code you'd like to be translated, please let me know which sections you'd like to translate, and I'll provide translations for those parts.
英文:
I have this design that I'm creating on Flutter:
Here is what I managed to do so far:
I'll provided you my code and I ll explain it and finally I'll try to explain the error that I'm having. First here is my code:
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(),
        ],
      ),
    );
  }
}
This code is mainly composed of a Scaffold, it's child is a Stack that stacks a back button (BackButton) on tap of a Column. This column has two containers SizedBox; the first one takes 16% of the height of the screen, and the second one takes 84% which makes a total of 100%. Inside the first SizedBox I defined a PageViewIndicator widget which is a Container that holds a Row that holds 3 HeadingPageViewItemWidget like this:
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']!,
            ),
          ],
        ),
      ),
    );
  }
}
The HeadingPageViewItemWidget is another Row that holds a CircleAvatar and a Text widget, like this:
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),
          ),
        ],
      ),
    );
  }
}
Inside the second SizedBox I have defined a PageView that has 3 children, QuantityStepWidget, PaymentStepWidget and ReviewStepWidget, these last two are just PlaceHolders for the moment. The QuantityStepWidget is defined like this:
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'),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}
It consists of a SingleChildScrollView and inside it there is a Column which holds thre Flexible widgets; the first one is the 'Quantity' title, the second one is the two cards of the medication name and quantity, and the third one is the form.
What I want is to make the form go up when the keyboard gets triggered, but it doesn't want to do that, all it does is to show the keyboard and then close it instanly, and it doesn't give me the time to add text, as soon as the keyboard opens it closes
答案1
得分: 1
在你的构建方法之外放置这两个:
final double height = MediaQuery.of(context).size.height;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
获取更多信息,请访问此线程:StackOverflow答案
英文:
Put These Two outside of your build method:
final double height = MediaQuery.of(context).size.height;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
For more information, visit this thread: StackOverflow answer
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。




评论