| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/material.dart'; |
| import 'package:flutter/services.dart'; |
| |
| void main() { |
| runApp(MaterialApp( |
| title: 'Hardware Key Demo', |
| home: Scaffold( |
| appBar: AppBar( |
| title: const Text('Hardware Key Demo'), |
| ), |
| body: const Center( |
| child: HardwareKeyboardDemo(), |
| ), |
| ), |
| )); |
| } |
| |
| class HardwareKeyboardDemo extends StatefulWidget { |
| const HardwareKeyboardDemo({super.key}); |
| |
| @override |
| State<HardwareKeyboardDemo> createState() => _HardwareKeyboardDemoState(); |
| } |
| |
| class _HardwareKeyboardDemoState extends State<HardwareKeyboardDemo> { |
| final FocusNode _focusNode = FocusNode(); |
| KeyEvent? _event; |
| |
| @override |
| void dispose() { |
| _focusNode.dispose(); |
| super.dispose(); |
| } |
| |
| KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) { |
| setState(() { |
| _event = event; |
| }); |
| return KeyEventResult.ignored; |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| final TextTheme textTheme = Theme.of(context).textTheme; |
| return Focus( |
| focusNode: _focusNode, |
| onKeyEvent: _handleKeyEvent, |
| autofocus: true, |
| child: AnimatedBuilder( |
| animation: _focusNode, |
| builder: (BuildContext context, Widget? child) { |
| if (!_focusNode.hasFocus) { |
| return GestureDetector( |
| onTap: () { |
| _focusNode.requestFocus(); |
| }, |
| child: Text('Tap to focus', style: textTheme.headlineMedium), |
| ); |
| } |
| |
| if (_event == null) { |
| return Text('Press a key', style: textTheme.headlineMedium); |
| } |
| |
| final List<Widget> dataText = <Widget>[ |
| Text('${_event.runtimeType}'), |
| if (_event?.character?.isNotEmpty ?? false) Text('character produced: "${_event?.character}"'), |
| ]; |
| dataText.add(Text('logical: ${_event?.logicalKey}')); |
| dataText.add(Text('physical: ${_event?.physicalKey}')); |
| if (_event?.character != null) { |
| dataText.add(Text('character: ${_event?.character}')); |
| } |
| final List<String> pressed = <String>['Pressed:']; |
| for (final LogicalKeyboardKey key in HardwareKeyboard.instance.logicalKeysPressed) { |
| pressed.add(key.debugName!); |
| } |
| dataText.add(Text(pressed.join(' '))); |
| return DefaultTextStyle( |
| style: textTheme.titleMedium!, |
| child: Column( |
| mainAxisAlignment: MainAxisAlignment.center, |
| children: dataText, |
| ), |
| ); |
| }, |
| ), |
| ); |
| } |
| } |