1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/foundation.dart';
6import 'package:flutter/services.dart';
7
8import 'focus_manager.dart';
9import 'focus_scope.dart';
10import 'framework.dart';
11
12export 'package:flutter/services.dart' show KeyEvent;
13
14/// A widget that calls a callback whenever the user presses or releases a key
15/// on a keyboard.
16///
17/// A [KeyboardListener] is useful for listening to key events and
18/// hardware buttons that are represented as keys. Typically used by games and
19/// other apps that use keyboards for purposes other than text entry.
20///
21/// For text entry, consider using a [EditableText], which integrates with
22/// on-screen keyboards and input method editors (IMEs).
23///
24/// See also:
25///
26/// * [EditableText], which should be used instead of this widget for text
27/// entry.
28class KeyboardListener extends StatelessWidget {
29 /// Creates a widget that receives keyboard events.
30 ///
31 /// For text entry, consider using a [EditableText], which integrates with
32 /// on-screen keyboards and input method editors (IMEs).
33 ///
34 /// The `key` is an identifier for widgets, and is unrelated to keyboards.
35 /// See [Widget.key].
36 const KeyboardListener({
37 super.key,
38 required this.focusNode,
39 this.autofocus = false,
40 this.includeSemantics = true,
41 this.onKeyEvent,
42 required this.child,
43 });
44
45 /// Controls whether this widget has keyboard focus.
46 final FocusNode focusNode;
47
48 /// {@macro flutter.widgets.Focus.autofocus}
49 final bool autofocus;
50
51 /// {@macro flutter.widgets.Focus.includeSemantics}
52 final bool includeSemantics;
53
54 /// Called whenever this widget receives a keyboard event.
55 final ValueChanged<KeyEvent>? onKeyEvent;
56
57 /// The widget below this widget in the tree.
58 ///
59 /// {@macro flutter.widgets.ProxyWidget.child}
60 final Widget child;
61
62 @override
63 Widget build(BuildContext context) {
64 return Focus(
65 focusNode: focusNode,
66 autofocus: autofocus,
67 includeSemantics: includeSemantics,
68 onKeyEvent: (FocusNode node, KeyEvent event) {
69 onKeyEvent?.call(event);
70 return KeyEventResult.ignored;
71 },
72 child: child,
73 );
74 }
75
76 @override
77 void debugFillProperties(DiagnosticPropertiesBuilder properties) {
78 super.debugFillProperties(properties);
79 properties.add(DiagnosticsProperty<FocusNode>('focusNode', focusNode));
80 }
81}
82