User interfaces must have keyboard shortcuts because they allow users to do tasks fast without only using mouse interactions. The CallbackShortcuts widget in Flutter lets you build keyboard shortcuts despite the framework’s lack of built-in handling of keyboard shortcuts like desktop programmes. We’ll look at how to use CallbackShortcuts tutorial to record and manage keyboard events.
What is CallbackShortcuts?
A Flutter widget called CallbackShortcuts enables you to binds key combinations to specific callbacks. You can create your own keyboard shortcuts and keyboard interactions since you have direct access to the keyboard input.
Read more about Flutter app development services from mobikul.
Steps to implement
The basic steps of using CallbackShortcuts
widget involves the following steps:
- Wrap your widgets with Focus widget (a widget that defines which widgets can receive keyboard focus) since widget focus affects keyboard events.
- Handle Keyboard Events :- Implement a Map with key as type of ShortcutActivator (information about the keys pressed) and value as VoidCallback function which execute when keyboard events triggered. Assign Map to the bindings property of CallbackShortcuts class.
- Wrap Relevant Widgets: Wrap the widgets that should respond to the keyboard events with the
.CallbackShortcuts
Implementation
Create a stateful class KeyboardShortcutExample and create simple counter app to increment and decrement the count value by one as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
class KeyboardShortcutExample extends StatefulWidget { const KeyboardShortcutExample({super.key}); @override State<KeyboardShortcutExample> createState() => _CallbackShortcutsExampleState(); } class _CallbackShortcutsExampleState extends State<KeyboardShortcutExample> { int count = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Callback example"), ), body: CallbackShortcuts( bindings: <ShortcutActivator, VoidCallback>{ const SingleActivator(LogicalKeyboardKey.arrowUp): () { setState((){ count = count + 1; }); }, const SingleActivator(LogicalKeyboardKey.arrowDown): () { setState((){ count = count - 1; }); }, }, child: Focus( autofocus: true, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Press the up arrow key to increase the count and down arrow key to decrease the count',style: TextStyle(fontSize: 18)), SizedBox(height: 8,), Text("$count", style: TextStyle(fontSize: 20),) ], ), ), ), )); } } |
In above example code When the arrow up key is hit on the keyboard, the callback method executes and increments the count value by one, while the setState function updates the UI.
LogicalKeyboardKey.arrowUp :- binds the arrow key up with increment count by 1.
LogicalKeyboardKey.arrowDown :- binds the arrow key down with decrement count by 1.
SingleActivator :- Represents a single key combined with modifiers (control, shift, alt).
CallbackShortcuts :- Accept child widget that respond to the keyboard event.
bindings :- Property of CallbackShortcuts that accept Map of Keyboard events and callback function.
Focus :- Allow this widget and its descendants to receive keyboard focus.
Want to learn about Keyboard Focus in flutter.
Output of example code
KeyboardShortcutExample
Full code example
Below is the full code example for handling keyboard events :-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
class KeyboardShortcutExample extends StatefulWidget { const KeyboardShortcutExample({super.key}); @override State<KeyboardShortcutExample> createState() => _CallbackShortcutsExampleState(); } class _CallbackShortcutsExampleState extends State<KeyboardShortcutExample> { final ScrollController _controller = ScrollController(); int quantity = 1; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Callback example"), ), body: SingleChildScrollView( controller: _controller, child: CallbackShortcuts( bindings: <ShortcutActivator, VoidCallback>{ const SingleActivator(LogicalKeyboardKey.keyA, shift: true): () { setState((){ quantity = quantity + 1; }); }, const SingleActivator(LogicalKeyboardKey.keyM, shift: true): () { setState((){ if(quantity > 0){ quantity = quantity - 1; } }); }, const SingleActivator(LogicalKeyboardKey.arrowUp): () { _scrollUp(); }, const SingleActivator(LogicalKeyboardKey.arrowDown): () { _scrollDown(); }, }, child: Focus( autofocus: true, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('1. Press the up arrow key to scroll the page up', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),), const Padding( padding: EdgeInsets.symmetric(vertical: 4.0), child: Text('2. Press the down arrow key to scroll the page down', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)), ), const Text('3. Press the keys Shift+A to increase quantity',style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)), const Padding( padding: EdgeInsets.only(top: 4, bottom: 10), child: Text('4. Press the keys Shift+M to decrease quantity',style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)), ), const Divider(), productWidget(quantity), ListView.builder( itemCount: 12, physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (context, idx){ return productWidget(idx); }), ], ), ), ), ), )); } Widget productWidget(int idx){ return Column( children: [ SizedBox( height: 130, child: Row(children: [ Image.network( "https://unsplash.com/photos/CrPAvN29Nhs/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjkzMjgyOTEwfA&force=true&w=640", height: 100, width: 100), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Main product title', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 16), ), const Padding( padding: EdgeInsets.symmetric(vertical: 4), child: Text('This is description of product'), ), const Text('Price : \$150'), Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Text('Total : \$${idx * 150}'), ), Expanded( child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ const Text("Quantity : "), const Icon(Icons.remove), Container( margin: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 4), decoration: BoxDecoration(border: Border.all()), child: Text("$idx"), ), const Icon(Icons.add), ], ), ) ], )), ]), ), const Divider() ], ); } void _scrollDown() { _controller.animateTo(_controller.position.pixels + 100, duration: const Duration(milliseconds: 100), curve: Curves.bounceInOut, ); } void _scrollUp() { _controller.animateTo(_controller.position.pixels -100, duration: const Duration(milliseconds: 100), curve: Curves.bounceInOut, ); } } |
Above code we have added scrolling feature also using the arrow keys up to scroll the page up and arrow key down to scroll the page down.
we have added productWidget inside ListView.builder class to generate content on the UI for scrolling and handling keyboard events.
You can also learn about callback in swift.
In bindings property we have defined four entries in map to handle four keyboard events as :
- SingleActivator(LogicalKeyboardKey.keyA, shift: true) : binds key combinations Shift+A and callback function to increase the quantity by one.
- SingleActivator(LogicalKeyboardKey.keyM, shift: true) : binds key combinations Shift+M, decrement the quantity by one when event triggered.
- SingleActivator(LogicalKeyboardKey.arrowUp) : Scroll the page up when arrow up key is pressed from keyboard.
- SingleActivator(LogicalKeyboardKey.arrowDown): Scroll the page down when arrow down key is pressed from keyboard.
_controller :- Control the scrolling effect in the UI or to add animation while scrolling.
Triggering event on click of button in android.
Output of full code example
Handling Keyboard Events
Conclusion
Thanks for reading this article ❤️
I hope this blog will help you to learn about how to Use CallbackShortcuts widget in flutter and you will be able to implement it. For more updates, make sure to keep following Mobikul Blogs to learn more about flutter and android.
Happy Learning ✍️