New to Flutter. I have a keyboard listener wrapping my Scaffold body to detect Enter and backspace key.
I noticed however: upon every page refresh, there will be additional listeners causing double firing of events. i.e. increment function triggered within the listener will double
I have to kill the browser and reopen the page to return to the initial state.
What's happening here? any best way to resolve this?
My code (selected relevant segments):
class MyHomePageState extends State<MyHomePage> {
static int counter = 0;
void _incrementCounter() {
setState(() {
counter++;
});
}
void _decrementCounter() {
setState(() {
if (counter > 0) {
counter--;
}
});
}
. . .
@override
Widget build(BuildContext context) {
return Scaffold(
bottomSheet: Container(
padding: EdgeInsets.all(5.0),
child: Text(
'Some text',
style: const TextStyle(
fontSize: 12.0,
),
textAlign: TextAlign.center,
),
),
body: RawKeyboardListener(
focusNode: FocusNode(),
onKey: (RawKeyEvent event) {
if (event.isKeyPressed(LogicalKeyboardKey.enter) ||
event.isKeyPressed(LogicalKeyboardKey.numpadEnter)) {
_incrementCounter();
}
if (event.isKeyPressed(LogicalKeyboardKey.backspace)) {
_decrementCounter();
}
},
autofocus: true,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
decoration: const BoxDecoration(.......
Thanks in advance!
Not the most beautiful solution but I managed to resolve this by separating one of the button and disposing the listener
_buildDefectButton() {
// ElevatedButton _button =
FocusScope.of(context).requestFocus(_focusNode);
return RawKeyboardListener(
focusNode: _focusNode,
autofocus: true,
onKey: (RawKeyEvent event) => {
if (event is RawKeyDownEvent)
{
_handleKeyPressed(_focusNode, event),
}
},
child: ElevatedButton.icon(
style: ButtonStyle(
padding:
MaterialStateProperty.all<EdgeInsets>(const EdgeInsets.all(20)),
),
label: const Text(
'Button pressed!',
style: TextStyle(
fontSize: 20.0,
),
),
onPressed: _incrementCounter,
icon: const Icon(Icons.sentiment_very_dissatisfied),
),
);
}
//Handle when keyPressed
_handleKeyPressed(FocusNode _focusNode, RawKeyEvent event) {
if (event is RawKeyDownEvent) {
if (event.isKeyPressed(LogicalKeyboardKey.enter) ||
event.isKeyPressed(LogicalKeyboardKey.numpadEnter)) {
_incrementCounter();
// return KeyEventResult.handled;
}
if (event.isKeyPressed(LogicalKeyboardKey.backspace)) {
_decrementCounter();
// return KeyEventResult.handled;
}
}
// return KeyEventResult.ignored;
}
and just adding
final FocusNode _focusNode = FocusNode();
@override
void initState() {
super.initState();
}
and
@override
void dispose() {
// The attachment will automatically be detached in dispose().
_focusNode.dispose();
super.dispose();
}
I did face some confusing situation in between if i return KeyEventResult.handled
which causes a double count whenever the keyboard button is pressed, but just handling the keyboard press without returning result and disposing the keynode at the end resolve my issue that listener will compound upon every refresh. Hope this helps anybody who might face similar confusion in the future.