androidflutterdartflutter-form-builder

Keyboard keeps going out of focus in flutter application


this is my flutter sign in widget, but the issue is, the moment i declare the form keys, the keyboard for every text field keeps going out of focus, how to resolve this, please help

class signin_form_widget extends StatelessWidget {
  signin_form_widget({
    super.key,
    required this.isDarkMode,
  });

  final bool isDarkMode;

  @override
  Widget build(BuildContext context) {

    final sController = Get.put(SignUpController());
    final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

    return GestureDetector(

      child: SingleChildScrollView(
        child: Form(
          //key: _formKey,// the moment i uncomment this line, my keyboard goes out of focus
          child: Container(
            width: 350,
            padding: const EdgeInsets.symmetric(vertical: 20.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Row(
                  children: [
                    Expanded(
                      child: Container(
                        margin: const EdgeInsets.only(right: 10),
                        decoration: BoxDecoration(
                          boxShadow: [
                            BoxShadow(
                              color: Colors.grey.withOpacity(0.2),
                              spreadRadius: 1,
                              blurRadius: 20,
                              offset: const Offset(0, 6),
                            ),
                          ],
                        ),
                        child: TextFormField(
                          controller: sController.fName,
                          decoration: InputDecoration(
                            prefixIcon: const Icon(Icons.person_outline_outlined),
                            hintText: fName,
                            filled: true,
                            fillColor: isDarkMode ? Colors.blueGrey[700] : Colors
                                .white,
                            border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(40.0),
                              borderSide: BorderSide.none,
                            ),
                          ),
                        ),
                      ),
                    ),
                    Expanded(
                      child: Container(
                        margin: const EdgeInsets.only(left: 10),
                        decoration: BoxDecoration(
                          boxShadow: [
                            BoxShadow(
                              color: Colors.grey.withOpacity(0.2),
                              spreadRadius: 1,
                              blurRadius: 20,
                              offset: const Offset(0, 6),
                            ),
                          ],
                        ),
                        child: TextFormField(
                          controller: sController.lName,
                          decoration: InputDecoration(
                            prefixIcon: const Icon(Icons.person_outline_outlined),
                            hintText: lName,
                            filled: true,
                            fillColor: isDarkMode ? Colors.blueGrey[700] : Colors
                                .white,
                            border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(40.0),
                              borderSide: BorderSide.none,
                            ),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 15.0),
                Container(
                  decoration: BoxDecoration(
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.2),
                        spreadRadius: 1,
                        blurRadius: 20,
                        offset: const Offset(0, 6),
                      ),
                    ],
                  ),
                  child: TextFormField(
                    controller: sController.email,
                    decoration: InputDecoration(
                      prefixIcon: const Icon(Icons.email_outlined),
                      hintText: email,
                      filled: true,
                      fillColor: isDarkMode ? Colors.blueGrey[700] : Colors.white,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(40.0),
                        borderSide: BorderSide.none,
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 15.0),
                Container(
                  decoration: BoxDecoration(
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.2),
                        spreadRadius: 1,
                        blurRadius: 20,
                        offset: const Offset(0, 6),
                      ),
                    ],
                  ),
                  child: TextFormField(
                    controller: sController.phone,
                    decoration: InputDecoration(
                      prefixIcon: const Icon(Icons.phone),
                      hintText: phone,
                      filled: true,
                      fillColor: isDarkMode ? Colors.blueGrey[700] : Colors.white,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(40.0),
                        borderSide: BorderSide.none,
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 15.0),
                Container(
                  decoration: BoxDecoration(
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.2),
                        spreadRadius: 1,
                        blurRadius: 20,
                        offset: const Offset(0, 6),
                      ),
                    ],
                  ),
                  child: TextFormField(
                    controller: sController.password,
                    decoration: InputDecoration(
                      prefixIcon: const Icon(Icons.lock_outline),
                      hintText: password,
                      filled: true,
                      fillColor: isDarkMode ? Colors.blueGrey[700] : Colors.white,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(40.0),
                        borderSide: BorderSide.none,
                      ),
                      suffixIcon: const IconButton(
                        onPressed: null,
                        icon: Icon(Icons.remove_red_eye_sharp),
                      ),
                    ),
                    obscureText: true,
                  ),
                ),
                const SizedBox(height: 15.0),
                Container(
                  decoration: BoxDecoration(
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.2),
                        spreadRadius: 1,
                        blurRadius: 20,
                        offset: const Offset(0, 6),
                      ),
                    ],
                  ),
                  child: TextFormField(
                    controller: sController.passconfirm,
                    decoration: InputDecoration(
                      prefixIcon: const Icon(Icons.lock_outline),
                      hintText: confirmpass,
                      filled: true,
                      fillColor: isDarkMode ? Colors.blueGrey[700] : Colors.white,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(40.0),
                        borderSide: BorderSide.none,
                      ),
                      suffixIcon: const IconButton(
                        onPressed: null,
                        icon: Icon(Icons.remove_red_eye_sharp),
                      ),
                    ),
                    obscureText: true,
                  ),
                ),
                const SizedBox(height: 20.0),
                Align(
                  alignment: Alignment.centerLeft,
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 40.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Center(
                          child: Text(
                            'By continuing, you agree to our ',
                            style: TextStyle(
                              color: isDarkMode ? Colors.white : Colors.black54,
                            ),
                            textAlign: TextAlign.center,
                          ),
                        ),
                        Center(
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              Expanded(
                                child: TextButton(
                                  onPressed: () {
                                    BottomSheetTerms.terms_bottomsheet(context);
                                  },
                                  child: const Text(
                                    'Terms of Use',
                                    style: TextStyle(color: Colors.blue),
                                  ),
                                ),
                              ),
                              Text(
                                ' and ',
                                style: TextStyle(
                                  color: isDarkMode ? Colors.white : Colors.black54,
                                ),
                              ),
                              Expanded(
                                child: TextButton(
                                  onPressed: () {
                                    BottomSheetPolicy.policy_bottomsheet(context);
                                  },
                                  child: const Text(
                                    'Privacy Policy',
                                    style: TextStyle(color: Colors.blue),
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),

                const SizedBox(height: 20.0),
                ElevatedButton(
                  onPressed: () {
                    if (_formKey.currentState!.validate())
                      {

                      }
                  },
                  style: ElevatedButton.styleFrom(
                    padding: const EdgeInsets.symmetric(
                        vertical: 5, horizontal: 40),
                    minimumSize: const Size(390, 60),
                  ),
                  child: const Text(
                    'Create Account',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 18,
                    ),
                    textAlign: TextAlign.center,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

}

I want the elevated button to perform validation and send it to firebase backend for authentication, using firebase_auth and firebase_core. but apparently it cant even send the data because the keyboard isnt even popping. i run the app on chrome as my device, it did process to the backend, but the moment i run it on mobile, the keyboard goes out of focus


Solution

  • You can use focuse node to open and close keyboard in flutter

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    class signin_form_widget extends StatefulWidget {
      final bool isDarkMode;
    
      signin_form_widget({super.key, required this.isDarkMode});
    
      @override
      _signin_form_widgetState createState() => _signin_form_widgetState();
    }
    
    class _signin_form_widgetState extends State<signin_form_widget> {
      final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
      late FocusNode fNameFocusNode;
      late FocusNode lNameFocusNode;
      late FocusNode emailFocusNode;
      late FocusNode phoneFocusNode;
      late FocusNode passwordFocusNode;
      late FocusNode passconfirmFocusNode;
    
      @override
      void initState() {
        super.initState();
        fNameFocusNode = FocusNode();
        lNameFocusNode = FocusNode();
        emailFocusNode = FocusNode();
        phoneFocusNode = FocusNode();
        passwordFocusNode = FocusNode();
        passconfirmFocusNode = FocusNode();
      }
    
      @override
      void dispose() {
        fNameFocusNode.dispose();
        lNameFocusNode.dispose();
        emailFocusNode.dispose();
        phoneFocusNode.dispose();
        passwordFocusNode.dispose();
        passconfirmFocusNode.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        final sController = Get.put(SignUpController());
    
        return GestureDetector(
          onTap: () {
            FocusScope.of(context).unfocus();
          },
          child: SingleChildScrollView(
            child: Form(
              key: _formKey,
              child: Container(
                width: 350,
                padding: const EdgeInsets.symmetric(vertical: 20.0),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Row(
                      children: [
                        Expanded(
                          child: Container(
                            margin: const EdgeInsets.only(right: 10),
                            decoration: BoxDecoration(
                              boxShadow: [
                                BoxShadow(
                                  color: Colors.grey.withOpacity(0.2),
                                  spreadRadius: 1,
                                  blurRadius: 20,
                                  offset: const Offset(0, 6),
                                ),
                              ],
                            ),
                            child: TextFormField(
                              focusNode: fNameFocusNode,
                              controller: sController.fName,
                              decoration: InputDecoration(
                                prefixIcon: const Icon(Icons.person_outline_outlined),
                                hintText: 'First Name',
                                filled: true,
                                fillColor: widget.isDarkMode ? Colors.blueGrey[700] : Colors.white,
                                border: OutlineInputBorder(
                                  borderRadius: BorderRadius.circular(40.0),
                                  borderSide: BorderSide.none,
                                ),
                              ),
                            ),
                          ),
                        ),
                        Expanded(
                          child: Container(
                            margin: const EdgeInsets.only(left: 10),
                            decoration: BoxDecoration(
                              boxShadow: [
                                BoxShadow(
                                  color: Colors.grey.withOpacity(0.2),
                                  spreadRadius: 1,
                                  blurRadius: 20,
                                  offset: const Offset(0, 6),
                                ),
                              ],
                            ),
                            child: TextFormField(
                              focusNode: lNameFocusNode,
                              controller: sController.lName,
                              decoration: InputDecoration(
                                prefixIcon: const Icon(Icons.person_outline_outlined),
                                hintText: 'Last Name',
                                filled: true,
                                fillColor: widget.isDarkMode ? Colors.blueGrey[700] : Colors.white,
                                border: OutlineInputBorder(
                                  borderRadius: BorderRadius.circular(40.0),
                                  borderSide: BorderSide.none,
                                ),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: 15.0),
                    Container(
                      decoration: BoxDecoration(
                        boxShadow: [
                          BoxShadow(
                            color: Colors.grey.withOpacity(0.2),
                            spreadRadius: 1,
                            blurRadius: 20,
                            offset: const Offset(0, 6),
                          ),
                        ],
                      ),
                      child: TextFormField(
                        focusNode: emailFocusNode,
                        controller: sController.email,
                        decoration: InputDecoration(
                          prefixIcon: const Icon(Icons.email_outlined),
                          hintText: 'Email',
                          filled: true,
                          fillColor: widget.isDarkMode ? Colors.blueGrey[700] : Colors.white,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(40.0),
                            borderSide: BorderSide.none,
                          ),
                        ),
                      ),
                    ),
                    const SizedBox(height: 15.0),
                    Container(
                      decoration: BoxDecoration(
                        boxShadow: [
                          BoxShadow(
                            color: Colors.grey.withOpacity(0.2),
                            spreadRadius: 1,
                            blurRadius: 20,
                            offset: const Offset(0, 6),
                          ),
                        ],
                      ),
                      child: TextFormField(
                        focusNode: phoneFocusNode,
                        controller: sController.phone,
                        decoration: InputDecoration(
                          prefixIcon: const Icon(Icons.phone),
                          hintText: 'Phone',
                          filled: true,
                          fillColor: widget.isDarkMode ? Colors.blueGrey[700] : Colors.white,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(40.0),
                            borderSide: BorderSide.none,
                          ),
                        ),
                      ),
                    ),
                    const SizedBox(height: 15.0),
                    Container(
                      decoration: BoxDecoration(
                        boxShadow: [
                          BoxShadow(
                            color: Colors.grey.withOpacity(0.2),
                            spreadRadius: 1,
                            blurRadius: 20,
                            offset: const Offset(0, 6),
                          ),
                        ],
                      ),
                      child: TextFormField(
                        focusNode: passwordFocusNode,
                        controller: sController.password,
                        decoration: InputDecoration(
                          prefixIcon: const Icon(Icons.lock_outline),
                          hintText: 'Password',
                          filled: true,
                          fillColor: widget.isDarkMode ? Colors.blueGrey[700] : Colors.white,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(40.0),
                            borderSide: BorderSide.none,
                          ),
                          suffixIcon: const IconButton(
                            onPressed: null,
                            icon: Icon(Icons.remove_red_eye_sharp),
                          ),
                        ),
                        obscureText: true,
                      ),
                    ),
                    const SizedBox(height: 15.0),
                    Container(
                      decoration: BoxDecoration(
                        boxShadow: [
                          BoxShadow(
                            color: Colors.grey.withOpacity(0.2),
                            spreadRadius: 1,
                            blurRadius: 20,
                            offset: const Offset(0, 6),
                          ),
                        ],
                      ),
                      child: TextFormField(
                        focusNode: passconfirmFocusNode,
                        controller: sController.passconfirm,
                        decoration: InputDecoration(
                          prefixIcon: const Icon(Icons.lock_outline),
                          hintText: 'Confirm Password',
                          filled: true,
                          fillColor: widget.isDarkMode ? Colors.blueGrey[700] : Colors.white,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(40.0),
                            borderSide: BorderSide.none,
                          ),
                          suffixIcon: const IconButton(
                            onPressed: null,
                            icon: Icon(Icons.remove_red_eye_sharp),
                          ),
                        ),
                        obscureText: true,
                      ),
                    ),
                    const SizedBox(height: 20.0),
                    Align(
                      alignment: Alignment.centerLeft,
                      child: Container(
                        padding: const EdgeInsets.symmetric(horizontal: 40.0),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Center(
                              child: Text(
                                'By continuing, you agree to our ',
                                style: TextStyle(
                                  color: widget.isDarkMode ? Colors.white : Colors.black54,
                                ),
                                textAlign: TextAlign.center,
                              ),
                            ),
                            Center(
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  Expanded(
                                    child: TextButton(
                                      onPressed: () {
                                        BottomSheetTerms.terms_bottomsheet(context);
                                      },
                                      child: const Text(
                                        'Terms of Use',
                                        style: TextStyle(color: Colors.blue),
                                      ),
                                    ),
                                  ),
                                  Text(
                                    ' and ',
                                    style: TextStyle(
                                      color: widget.isDarkMode ? Colors.white : Colors.black54,
                                    ),
                                  ),
                                  Expanded(
                                    child: TextButton(
                                      onPressed: () {
                                        BottomSheetPolicy.policy_bottomsheet(context);
                                      },
                                      child: const Text(
                                        'Privacy Policy',
                                        style: TextStyle(color: Colors.blue),
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                    const SizedBox(height: 20.0),
                    ElevatedButton(
                      onPressed: () {
                        if (_formKey.currentState!.validate()) {
                        }
                      },
                      style: ElevatedButton.styleFrom(
                        padding: const EdgeInsets.symmetric(
                            vertical: 5, horizontal: 40),
                        minimumSize: const Size(390, 60),
                      ),
                      child: const Text(
                        'Create Account',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 18,
                        ),
                        textAlign: TextAlign.center,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }