skip to Main Content

I have created a custom Numpad widget in my Flutter app.

Custom Numpad and textfields

  class NumPadCheckout extends StatelessWidget {
  final TextEditingController controller;
  final Function delete;
  final Function onSubmit;

  const NumPadCheckout({
    Key? key,
    required this.delete,
    required this.onSubmit,
    required this.controller,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const SizedBox(height: 20),
        Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            NumberButtonCheckout(
              number: "1",
              controller: controller,
            ),
            NumberButtonCheckout(
              number: "2",
              controller: controller,
            ),
            NumberButtonCheckout(
              number: "3",
              controller: controller,
            ),
          ],
        ),
        // const SizedBox(height: 20),
        Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            NumberButtonCheckout(
              number: "4",
              controller: controller,
            ),
            NumberButtonCheckout(
              number: "5",
              controller: controller,
            ),
            NumberButtonCheckout(
              number: "6",
              controller: controller,
            ),
          ],
        ),
        // const SizedBox(height: 20),
        Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            NumberButtonCheckout(
              number: "7",
              controller: controller,
            ),
            NumberButtonCheckout(
              number: "8",
              controller: controller,
            ),
            NumberButtonCheckout(
              number: "9",
              controller: controller,
            ),
          ],
        ),
        // const SizedBox(height: 20),
        Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            // this button is used to delete the last number
            NumberButtonCheckout(
              number: "00",
              controller: controller,
            ),
            NumberButtonCheckout(
              number: "0",
              controller: controller,
            ),
            CustomKey(
              iconData: Icons.keyboard_backspace,
              onPressed: () => delete,
            )
          ],
        ),
      ],
    );
  }
}


class NumberButtonCheckout extends StatelessWidget {
  final String number;
  final TextEditingController controller;

  const NumberButtonCheckout({
    Key? key,
    required this.number,
    required this.controller,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: width,
      height: height,
      child: ElevatedButton(
        onPressed: () {
          controller.text += number.toString();
        },
        child: Center(
          child: Text(
            number.toString(),
          ),
        ),
      ),
    );
  }
}

class CustomKey extends StatelessWidget {
  final IconData iconData;
  final VoidCallback? onPressed;

  const CustomKey({
    Key? key,
    required this.iconData,
    required this.onPressed,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: width,
      height: height,
      child: ElevatedButton(
        onPressed: () => onPressed,
        child:  Center(
          child: Icon(
              iconData
          ),
        ),
      ),
    );
  }
}

Now I want to add this in a Screen and use it to input numbers to multiple TextFormFields I have on the same screen. Each TextFormField should have its own TextEditingControllers.And need to clear data when the backspace is in the numpad as well. How can I do this in Flutter?

2

Answers


  1. Obviously, with 2 (or more) text fields, we need 2 TextEdittingController. As your requirements, this Numpad will be used by both 2 text fields. So the question is: How do we know which text field is being typed?

    Oh, problem is clearer now. I suggest you use 2 FocusNode, which are called cashFocusNode & creditFocusNode and attach them into 2 TextEdittingController (and don’t forget to dispose).

    With NumberButtonCheckout, you could code its onPressed function like this:

      NumberButtonCheckout(
        onPressed: () => onPressedNumber(number);
      )
    

      void onPressedNumber(String number) {
        if (cashFocusNode.hasFocus) {
          cashTextEdittingController.text += number;
        } else if (creditFocusNode.hasFocus) {
          creditTextEdittingController.text += number;
        } else {
          // do nothing if no text field is being typed
        }
      }
    

    Do the same thing CustomKey with backspace.

    Edit: Oh right, I almost forgot. If we using focus node, the phone’s keyboard will show up. It leads us to this post: Flutter How to always hide keyboard when click on TextField but keep focus(Keep show cursor)

    Login or Signup to reply.
  2. You could do something like this:

      final TextEditingController _cashAmountController = TextEditingController();
      final TextEditingController _creditAmountController = TextEditingController();
      late TextEditingController _activeController;
    
    
      @override
      void initState() {
        super.initState();
        _activeController = _cashAmountController;
      }
    

    Then in your build method, you could have this:

    Column(
          children: [
            //cash amount textfield
            TextField(
              onTap: () {
                //change the active controller when the textfield is tapped on (focused)
                _activeController = _cashAmountController;
              },
            ),
    
            //credit amount textfield
            TextField(
              onTap: () {
                //change the active controller when the textfield is tapped on (focused)
                _activeController = _creditAmountController;
              },
            ),
            Expanded(
              child: NumPadCheckout(
                controller: _activeController,
                delete: onDelete,
                submit: onSubmit,
              ),
            ),
          ],
        )
    

    You could also use FocusNode as suggested by Nguyen Family but remember to set the keyboardType of your TextField to TextInputType.none

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search