I am using a handheld barcode scanner to scan a barcode. I couldn't get it to work without tracking keyboard input. It now works MOST of the time, but sometimes if I scan #COUNTING-TEST-TEST it will miss letters and result in something like #COUN-T.
Barcode type is Code-128 and scanner is Zebra DS2208
I am using an Amazon Fire Tablet, If I scan on desktop it works perfectly.
Has anyone had success with this?
class CustomTextFieldState extends State<CustomTextField> {
String _inputBuffer = ''; // Buffer to accumulate input
Timer? _bufferTimer; // Timer for clearing buffer
// Method to manually trigger onSubmitted
void submit() {
if (widget.onSubmitted != null) {
widget.onSubmitted!(widget.controller.text);
widget.controller.clear();
_inputBuffer = "";
widget.focusNode.requestFocus();
}
}
KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) {
if (event is KeyDownEvent) {
final LogicalKeyboardKey logicalKey = event.logicalKey;
final String key = event.character ?? '';
// Handle Enter key only when LogicalKeyboardKey.enter is pressed
if (logicalKey == LogicalKeyboardKey.enter) {
// Call onSubmitted with buffered input
widget.onSubmitted?.call(_inputBuffer);
// Clear the controller text and input buffer
widget.controller.clear();
_inputBuffer = '';
widget.focusNode.requestFocus();
return KeyEventResult.handled;
}
// Handle Backspace key
else if (logicalKey == LogicalKeyboardKey.backspace) {
if (_inputBuffer.isNotEmpty) {
// Remove the last character from the buffer
_inputBuffer = _inputBuffer.substring(0, _inputBuffer.length - 1);
widget.controller.text = _inputBuffer;
}
return KeyEventResult.handled;
}
// Handle normal characters: add them to the buffer and update the controller
else if (key.isNotEmpty && key.length == 1) {
// Add the character to the buffer and update the controller text
_inputBuffer += key;
widget.controller.text = _inputBuffer; // Reflect the key in the text field
return KeyEventResult.handled;
}
}
return KeyEventResult.ignored;
}
void _resetBufferTimer() {
_bufferTimer?.cancel();
_bufferTimer = Timer(widget.bufferDuration, () {
setState(() {
_inputBuffer = ''; // Clear buffer if no input for bufferDuration
});
});
}
@override
void dispose() {
_bufferTimer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Focus(
focusNode: widget.focusNode,
onKeyEvent: _handleKeyEvent, // Handle key events here
child: TextField(
autocorrect: false,
autofocus: true,
textInputAction: TextInputAction.done,
controller: widget.controller,
textCapitalization: TextCapitalization.none,
decoration: InputDecoration(
labelText: widget.labelText,
border: const OutlineInputBorder(),
prefixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
widget.controller.clear();
setState(() {
_inputBuffer = ''; // Clear the buffer as well
});
},
)
),
),
);
}
}
I have tried using stream_transform package, queues, buffers. I even tried registering native android edit text if Platform is android, but that came with its own complications, although it was able to read the rapid input very well.
So I was finally able to get it. I used the flutter_barcode_listener package with a little bit of customization.
void _handleBarcodeScan(String scannedCode) async {
if (!widget.focusNode.hasFocus) {
return;
}
setState(() {
// scannedcode came in with extra whitespace
_scannedText = scannedCode.trim();
// Scanner configured with enter after scan came in with `a` at the end
if (_scannedText.endsWith("`a`")) {
// # was transformed to 3 I needed to only remove the first 3 since
that is the only spot # will be
_scannedText = _scannedText.replaceFirst("3", "#");
}
// If user manually entered text then often times _scannedText would be
// empty so instead I got the text from the widget
if (_scannedText == "" && widget.controller.text != ""){
_scannedText = widget.controller.text.toUpperCase();
}
// Replace all specific characters as needed
_scannedText = _scannedText
.replaceAll("½", "-")
.replaceAll("``a`", "")
.replaceAll(RegExp(r"\s+"), "") // Remove all spaces, including multiple spaces
.replaceAll("¡3", "#"); // # would sometimes come in as that weird
// character as well
});
widget.controller.clear();
widget.onBarcodeComplete(_scannedText);
}
@override
Widget build(BuildContext context) {
return BarcodeKeyboardListener(
bufferDuration: widget.bufferDuration,
onBarcodeScanned: _handleBarcodeScan,
child: TextField(
controller: widget.controller,
focusNode: widget.focusNode,
textCapitalization: TextCapitalization.none,
decoration: InputDecoration(
labelText: widget.labelText,
border: const OutlineInputBorder(),
prefixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
widget.controller.clear();
setState(() {
_scannedText = '';
});
},
),
),
onChanged: _onTextChanged,
onSubmitted: (value) {
},
),
);
}
}