我有一个模拟键盘输入的RFID阅读器。我想在Flutter应用程序中获取卡号,然后提交给api。我已经尝试过onChanged事件,但是它会在读者发送所有卡号之前触发。如果我尝试使用onSubmitted进行操作,则此操作永远不会触发,因为读卡器会在输入所有卡号后都模拟回车。请帮助
我尝试过onChanged,它会在阅读器打印出第一位数字后立即触发,这是错误的,因为我需要所有数字,而且onSubmitted也不会触发,因为它不适用于外部键盘Enter键。我也尝试过RawKeyboardListener,但是随后所有按键都发送到RawKeyboardListener,并且TextBox中没有要发送的输入。
我希望一旦读取了所有卡号,然后将其发送到TextBox,然后应将其自动提交给api,而不是单击按钮作为“提交按钮”。
class _TagCardState extends State<TagCard> {
final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final cardController = new TextEditingController();
final focusNode = new FocusNode();
final keyboardNode = new FocusNode();
StudentData currentStudent = StudentData(name: "Ready to Tag");
final TextStyle h1 = TextStyle(fontSize: 20.0);
final TextStyle h2 = TextStyle(fontSize: 16.0);
@override
void initState(){
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => afterFirstLayout(context));
keyboardNode.addListener((){
if(keyboardNode.hasFocus){
print("keyboard focused");
}
});
focusNode.addListener((){
if(keyboardNode.hasFocus){
print("texbox focused");
}
});
}
@override
void dispose(){
cardController.dispose();
focusNode.dispose();
keyboardNode.dispose();
super.dispose();
}
void afterFirstLayout(BuildContext context) {
FocusScope.of(context).requestFocus(keyboardNode);
}
void _handleKeyEvent(RawKeyEvent key) {
final _kEnter = 66;
if (key is RawKeyDownEvent && key.data is RawKeyEventDataAndroid) {
RawKeyDownEvent ev = key;
RawKeyEventDataAndroid evAndroid = ev.data;
print(evAndroid.keyCode);
if(evAndroid.keyCode == _kEnter){
print("Enter Key");
print("Text box value :" + cardController.text);
// FocusScope.of(context).requestFocus(focusNode);
}
}
}
void resetStudentData() {
this.setState((){
this.currentStudent = StudentData(name: "Ready to Tag");
FocusScope.of(context).requestFocus(keyboardNode);
});
}
void showLoading() {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: Center(child:CircularProgressIndicator()),
content: Container(
alignment: AlignmentDirectional.center,
height: 50.0,
child: Text("Loading...")
),
),
);
}
void sendRequest(cardNumber) async {
final data = {
"card_number" : cardNumber
};
focusNode.unfocus();
this.showLoading();
httpPut("student/card/tag", data).then((response) {
cardController.clear();
Navigator.of(context).pop();
Map responseData = json.decode(response);
print(responseData);
if(responseData['success']){
this.setState((){
this.currentStudent = StudentData(
name: responseData['data']['student_name'],
cls: responseData['data']['class'],
rollNumber: responseData['data']['roll_number'],
image: responseData['data']['image'],
in_out: responseData['data']['in_out'].toUpperCase()
);
FocusScope.of(context).requestFocus(keyboardNode);
new Future.delayed(new Duration(seconds: 3), resetStudentData);
});
}
else {
FocusScope.of(context).requestFocus(keyboardNode);
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text(responseData['message']),
backgroundColor: Colors.red,
)
);
}
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("KMV Attandence"),
),
body: Container(
alignment: AlignmentDirectional.center,
padding: EdgeInsets.all(20.0),
child: Form(
key: _formKey,
child: Center(
child: ListView(
shrinkWrap: true,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RawKeyboardListener(
child: TextField(
enabled: true,
obscureText: false,
controller: cardController,
onSubmitted: (text) => this.sendRequest(text),
textAlign: TextAlign.center,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Tag Card'
),
),
focusNode: keyboardNode,
onKey: (key) => _handleKeyEvent(key),
),
Text(this.currentStudent.name, style: this.h1),
Text(this.currentStudent.cls, style: this.h2),
Text(this.currentStudent.rollNumber, style: this.h2),
Container(
decoration: BoxDecoration(
color: Colors.green
),
child: Text(this.currentStudent.in_out, style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
)),
)
],
),
]
)
)
)
)
);
}
}
class StudentData {
final String name;
final String cls;
final String rollNumber;
final String image;
final String in_out;
const StudentData({
this.name = "",
this.cls = "",
this.rollNumber = "",
this.image = "",
this.in_out = ""
});
[√] Flutter (Channel beta, v1.0.0, on Microsoft Windows [Version 10.0.17134.471], locale en-IN) • Flutter version 1.0.0 at C:\flutter • Framework revision 5391447fae (6 weeks ago), 2018-11-29 19:41:26 -0800 • Engine revision 7375a0f414 • Dart version 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297) [√] Android toolchain - develop for Android devices (Android SDK 28.0.3) • Android SDK at C:\Android\Sdk • Android NDK location not configured (optional; useful for native profiling support) • Platform android-28, build-tools 28.0.3 • ANDROID_HOME = C:\Android\Sdk • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02) • All Android licenses accepted. [√] Android Studio (version 3.1) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin version 29.0.1 • Dart plugin version 173.4700 • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02) [√] Connected device (1 available) • Android SDK built for x86 64 • emulator-5554 • android-x64 • Android 8.0.0 (API 26) (emulator) • No issues found!