我想實施年齡驗證程序,但要獲得年齡,我需要可以輸入生日的文本欄位。這是我現在擁有的文本欄位的代碼:
class TextFieldAgeInput extends StatelessWidget {
TextFieldAgeInput({
Key? key,
required this.textController,
required this.leftPadding,
required this.hintText,
}) : super(key: key);
TextEditingController textController;
double leftPadding;
String hintText;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(
left: leftPadding,
top: 5,
),
child: Container(
height: 40,
width: 30,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(10),
border: Border.all(
width: 1,
color: primaryColor,
),
),
child: Padding(
padding: const EdgeInsets.only(
bottom: 5,
left: 1,
),
child: TextField(
keyboardType: TextInputType.number,
style: GoogleFonts.poppins(
textStyle: const TextStyle(
color: mainTextColor,
fontSize: 15,
fontWeight: FontWeight.w600,
),
),
textAlign: TextAlign.center,
controller: textController,
decoration: InputDecoration(
hintText: hintText,
hintStyle: GoogleFonts.poppins(
textStyle: const TextStyle(
color: primaryColor,
fontSize: 11,
fontWeight: FontWeight.w600,
),
),
border: InputBorder.none,
),
onChanged: (textController) {
TextInputAction.next;
},
),
),
),
);
}
}
在螢屏的代碼中,我使用填充等多次呼叫小部件。現在,當給出 1 個數字(鍵盤 = numberkeyboard)時,如何使文本欄位切換到下一個?
我在這里先向您的幫助表示感謝
uj5u.com熱心網友回復:
您的代碼中存在基本錯誤,如下所示:
onChanged: (textController) {
TextInputAction.next;
},
該onChanged屬性是為您提供更新文本的回呼。它不給你textController。在正文中,您正在使用什么都不做的定義TextInputAction.next;。這應該分配給TextFieldas keyboardType: TextInputType.number。
無論如何,下面是我不久前寫的一個完全可運行的示例,它解決了您要解決的相同問題。該示例用于驗證碼,但也適用于出生年份(因為兩者都是四個欄位)。
在示例中,您會看到每個欄位都有自己的TextEditingController和FocusNode。我們使用控制器來設定/檢索值,而焦點節點用于將焦點從一個欄位移動到另一個欄位。
該示例還使用一種變通方法來檢測用戶何時單擊退格鍵(請參見底部的注釋),因此您會看到zero width space角色添加到控制器中,但在我們添加到時被洗掉code(在您的示例中為年齡)。代碼中有關于此的注釋。
您可以在此處查看 DartPad 上運行的代碼:多個文本欄位示例,或者您可以將其復制到編輯器并運行它:
// ignore_for_file: avoid_function_literals_in_foreach_calls, avoid_print
import 'package:flutter/material.dart';
void main() => runApp(MultipleTextFieldsExampleApp());
class MultipleTextFieldsExampleApp extends StatelessWidget {
const MultipleTextFieldsExampleApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
const MyHomePage({Key? key, required this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: const Center(child: CodeField()),
);
}
}
/// zero-width space character
///
/// this character can be added to a string to detect backspace.
/// The value, from its name, has a zero-width so it's not rendered
/// in the screen but it'll be present in the String.
///
/// The main reason this value is used because in Flutter mobile,
/// backspace is not detected when there's nothing to delete.
const zwsp = '\u200b';
// the selection is at offset 1 so any character is inserted after it.
const zwspEditingValue = TextEditingValue(text: zwsp, selection: TextSelection(baseOffset: 1, extentOffset: 1));
class CodeField extends StatefulWidget {
const CodeField({Key? key}) : super(key: key);
@override
_CodeFieldState createState() => _CodeFieldState();
}
class _CodeFieldState extends State<CodeField> {
List<String> code = ['', '', '', ''];
late List<TextEditingController> controllers;
late List<FocusNode> focusNodes;
@override
void initState() {
super.initState();
focusNodes = List.generate(4, (index) => FocusNode());
controllers = List.generate(4, (index) {
final ctrl = TextEditingController();
ctrl.value = zwspEditingValue;
return ctrl;
});
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
// give the focus to the first node.
focusNodes[0].requestFocus();
});
}
void printValues() {
print(code);
}
@override
void dispose() {
super.dispose();
focusNodes.forEach((focusNode) {
focusNode.dispose();
});
controllers.forEach((controller) {
controller.dispose();
});
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
4,
(index) {
return Container(
width: 20,
height: 20,
margin: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: TextField(
controller: controllers[index],
focusNode: focusNodes[index],
maxLength: 2,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
counterText: "",
),
onChanged: (value) {
if (value.length > 1) {
// this is a new character event
if (index 1 == focusNodes.length) {
// do something after the last character was inserted
FocusScope.of(context).unfocus();
} else {
// move to the next field
focusNodes[index 1].requestFocus();
}
} else {
// this is backspace event
// reset the controller
controllers[index].value = zwspEditingValue;
if (index == 0) {
// do something if backspace was pressed at the first field
} else {
// go back to previous field
controllers[index - 1].value = zwspEditingValue;
focusNodes[index - 1].requestFocus();
}
}
// make sure to remove the zwsp character
code[index] = value.replaceAll(zwsp, '');
print('current code = $code');
},
),
);
},
),
);
}
}
在 Flutter 中,當 TextField 為空時不會觸發退格onChanged,這就是解決方法存在的原因。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/410662.html
標籤:
