I’m working on a Flutter application where I need to focus and allow to write on a TextField when a button is clicked, but without showing the keyboard. I have a barcode scanner that inputs text into the focused field automatically, so I need the cursor to be in the TextField, but I don’t want the on-screen keyboard to appear.
Here’s my version
name: jtekt_mobile
description: "A new Flutter project."
publish_to: "none"
version: 0.1.0
environment:
sdk: ">=3.3.3 <4.0.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.0
flutter:
uses-material-design: true
Here’s my code
import 'package:flutter/material.dart';
import 'package:jtekt_mobile/models/mean_model.dart';
class Mean extends StatefulWidget {
const Mean({super.key});
@override
State<Mean> createState() => _MeanState();
}
class _MeanState extends State<Mean> {
bool isInOutSelected = false;
bool isNameSelected = false;
bool exitSelected = false;
bool entrySelected = false;
Color redColor = Colors.red;
Color greenColor = Colors.green;
Color greyColor = Colors.grey;
List<MeanModel> meanList = [];
final FocusNode nameFocusNode = FocusNode();
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: entryButton,
style: ElevatedButton.styleFrom(
backgroundColor: !isInOutSelected || entrySelected
? greenColor
: greyColor,
),
child: const Text(
"Entrée",
style: TextStyle(color: Colors.white),
),
),
ElevatedButton(
onPressed: exitButton,
style: ElevatedButton.styleFrom(
backgroundColor:
!isInOutSelected || exitSelected ? redColor : greyColor,
),
child: const Text(
"Sortie",
style: TextStyle(color: Colors.white),
),
),
],
),
),
),
if (isInOutSelected)
Expanded(
flex: 5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(10),
child: TextField(
focusNode: nameFocusNode,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: entrySelected ? greenColor : redColor,
width: 4),
),
border: const OutlineInputBorder(),
labelText: ("Nom"),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: entrySelected ? greenColor : redColor,
width: 2),
),
),
),
),
const SizedBox(height: 20),
if (isNameSelected)
const Padding(
padding: EdgeInsets.all(10),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: ("Moyen"),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black, width: 2),
),
),
),
),
const SizedBox(height: 20),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: meanList
.map((mean) => ListTile(
title: Text(mean.username),
subtitle: Text(mean.meanNumber),
trailing: const Icon(Icons.delete),
))
.toList(),
),
),
),
if (isNameSelected)
Center(
child: ElevatedButton(
onPressed: validation,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
),
child: const Text(
"Valider",
style: TextStyle(color: Colors.white),
),
),
),
const SizedBox(height: 20),
],
),
),
],
);
}
void entryButton() {
setState(() {
isInOutSelected = true;
entrySelected = true;
exitSelected = false;
});
nameFocusNode.requestFocus();
}
void exitButton() {
setState(() {
isInOutSelected = true;
exitSelected = true;
entrySelected = false;
});
nameFocusNode.requestFocus();
}
void validation() {}
}
What I want is when I click on the "Entrée" or "Sortie" button, it should set the focus on the "Nom" TextField and show the cursor, but without displaying the keyboard. I need to be able to input text into the TextField using a barcode scanner which automatically inputs text into the focused field.
I’ve tried various methods like SystemChannels.textInput.invokeMethod(‘TextInput.hide’), FocusNode().unfocus(), FocusManager.instance.primaryFocus?.unfocus(), FocusScope.of(context).unfocus(), and even using the input_with_keyboard_control (https://pub.dev/packages/input_with_keyboard_control/versions) library, but none of them worked (maybe for that i dont know how to use it)
I’ve seen this video very simple but it doesn’t work when i do the same in my code : https://www.youtube.com/watch?v=MKrEJtheGPk&t=59s
I’ve spent hours searching for a solution but haven’t found anything that works. How can I achieve this behavior in Flutter? Any help would be greatly appreciated.
2
Answers
There is actually a much simpler way to do this. Create a TextEditingController and assign it to your TextField. Then when you scan the bar code, use the controller to update the text.
You don’t actually need to focus the TextField to edit what’s inside of it. You can also prevent the keyboard from showing when the field is focused by setting
readOnly
to true:You can prevent the keyboard from appearing by setting
readOnly : true
inTextField
.And after tapping your QR scanner button and getting your text, you can update the presented text in the
TextField
by the controller.