dart Flutter:如何在Flutter中实现多个TextFormField的屏幕数字键盘?

c9qzyr3d  于 2023-10-13  发布在  Flutter
关注(0)|答案(2)|浏览(161)

我在我的Flutter应用程序中创建了一个自定义的Numpad小部件。

  1. class NumPadCheckout extends StatelessWidget {
  2. final TextEditingController controller;
  3. final Function delete;
  4. final Function onSubmit;
  5. const NumPadCheckout({
  6. Key? key,
  7. required this.delete,
  8. required this.onSubmit,
  9. required this.controller,
  10. }) : super(key: key);
  11. @override
  12. Widget build(BuildContext context) {
  13. return Column(
  14. children: [
  15. const SizedBox(height: 20),
  16. Row(
  17. mainAxisAlignment: MainAxisAlignment.start,
  18. children: [
  19. NumberButtonCheckout(
  20. number: "1",
  21. controller: controller,
  22. ),
  23. NumberButtonCheckout(
  24. number: "2",
  25. controller: controller,
  26. ),
  27. NumberButtonCheckout(
  28. number: "3",
  29. controller: controller,
  30. ),
  31. ],
  32. ),
  33. // const SizedBox(height: 20),
  34. Row(
  35. mainAxisAlignment: MainAxisAlignment.start,
  36. children: [
  37. NumberButtonCheckout(
  38. number: "4",
  39. controller: controller,
  40. ),
  41. NumberButtonCheckout(
  42. number: "5",
  43. controller: controller,
  44. ),
  45. NumberButtonCheckout(
  46. number: "6",
  47. controller: controller,
  48. ),
  49. ],
  50. ),
  51. // const SizedBox(height: 20),
  52. Row(
  53. mainAxisAlignment: MainAxisAlignment.start,
  54. children: [
  55. NumberButtonCheckout(
  56. number: "7",
  57. controller: controller,
  58. ),
  59. NumberButtonCheckout(
  60. number: "8",
  61. controller: controller,
  62. ),
  63. NumberButtonCheckout(
  64. number: "9",
  65. controller: controller,
  66. ),
  67. ],
  68. ),
  69. // const SizedBox(height: 20),
  70. Row(
  71. mainAxisAlignment: MainAxisAlignment.start,
  72. children: [
  73. // this button is used to delete the last number
  74. NumberButtonCheckout(
  75. number: "00",
  76. controller: controller,
  77. ),
  78. NumberButtonCheckout(
  79. number: "0",
  80. controller: controller,
  81. ),
  82. CustomKey(
  83. iconData: Icons.keyboard_backspace,
  84. onPressed: () => delete,
  85. )
  86. ],
  87. ),
  88. ],
  89. );
  90. }
  91. }
  92. class NumberButtonCheckout extends StatelessWidget {
  93. final String number;
  94. final TextEditingController controller;
  95. const NumberButtonCheckout({
  96. Key? key,
  97. required this.number,
  98. required this.controller,
  99. }) : super(key: key);
  100. @override
  101. Widget build(BuildContext context) {
  102. return SizedBox(
  103. width: width,
  104. height: height,
  105. child: ElevatedButton(
  106. onPressed: () {
  107. controller.text += number.toString();
  108. },
  109. child: Center(
  110. child: Text(
  111. number.toString(),
  112. ),
  113. ),
  114. ),
  115. );
  116. }
  117. }
  118. class CustomKey extends StatelessWidget {
  119. final IconData iconData;
  120. final VoidCallback? onPressed;
  121. const CustomKey({
  122. Key? key,
  123. required this.iconData,
  124. required this.onPressed,
  125. }) : super(key: key);
  126. @override
  127. Widget build(BuildContext context) {
  128. return SizedBox(
  129. width: width,
  130. height: height,
  131. child: ElevatedButton(
  132. onPressed: () => onPressed,
  133. child: Center(
  134. child: Icon(
  135. iconData
  136. ),
  137. ),
  138. ),
  139. );
  140. }
  141. }

现在我想在一个屏幕中添加这个,并使用它来输入数字到同一屏幕上的多个TextFormField中。每个TextFormField都应该有自己的TextEditingControllers。当退格键在数字键盘中时,也需要清除数据。如何在Flutter中做到这一点?

jckbn6z7

jckbn6z71#

由于您有2个文本字段,因此需要为每个 * 文本字段(两个文本字段都需要2个控制器)使用一个控制器。您可以创建一个第三个控制器,以了解当前正在使用的文本字段。
你可以这样做:

  1. final TextEditingController _cashAmountController = TextEditingController();
  2. final TextEditingController _creditAmountController = TextEditingController();
  3. late TextEditingController _activeController;
  4. @override
  5. void initState() {
  6. super.initState();
  7. _activeController = _cashAmountController;
  8. }

第三个控制器是您将传递给NumPadCheckout的控制器,以便在选择另一个TextField时,它会为新选择的TextField获取正确的控制器

现在您需要根据选定的TextField更改第三个控制器的值。TextField有一个onTap属性,您可以使用该属性将您的第三个控制器设置为该TextField的控制器。
在你的构建方法中,你可以这样做:

  1. Column(
  2. children: [
  3. //cash amount textfield
  4. TextField(
  5. onTap: () {
  6. //change the active controller when the textfield is tapped on (focused)
  7. _activeController = _cashAmountController;
  8. },
  9. ),
  10. //credit amount textfield
  11. TextField(
  12. onTap: () {
  13. //change the active controller when the textfield is tapped on (focused)
  14. _activeController = _creditAmountController;
  15. },
  16. ),
  17. Expanded(
  18. child: NumPadCheckout(
  19. controller: _activeController,
  20. delete: onDelete,
  21. submit: onSubmit,
  22. ),
  23. ),
  24. ],
  25. )

您也可以使用Nguyen Family建议的FocusNode,但请记住将TextField的keyboardType设置为TextInputType。none

展开查看全部
332nm8kg

332nm8kg2#

显然,对于2个(或更多)文本字段,我们需要2个TextEdittingController。根据您的要求,此数字键盘将用于两个文本字段。所以问题是:我们如何知道正在键入哪个文本字段?
噢,现在问题更清楚了。我建议你使用2个FocusNode,它们被称为cashFocusNodecreditFocusNode,并将它们附加到2个TextEdittingController中(不要忘记处理)。
使用NumberButtonCheckout,可以像这样编写onPressed函数:

  1. NumberButtonCheckout(
  2. onPressed: () => onPressedNumber(number);
  3. )

...

  1. void onPressedNumber(String number) {
  2. if (cashFocusNode.hasFocus) {
  3. cashTextEdittingController.text += number;
  4. } else if (creditFocusNode.hasFocus) {
  5. creditTextEdittingController.text += number;
  6. } else {
  7. // do nothing if no text field is being typed
  8. }
  9. }

用backspace做同样的事情CustomKey

展开查看全部

相关问题