FocusScopeNode class Null safety

A subclass of FocusNode that acts as a scope for its descendants, maintaining information about which descendant is currently or was last focused.

Please see the FocusScope and Focus widgets, which are utility widgets that manage their own FocusScopeNodes and FocusNodes, respectively. If they aren't appropriate, FocusScopeNodes can be managed directly.

FocusScopeNode organizes FocusNodes into scopes. Scopes form sub-trees of nodes that can be traversed as a group. Within a scope, the most recent nodes to have focus are remembered, and if a node is focused and then removed, the original node receives focus again.

From a FocusScopeNode, calling setFirstFocus, sets the given focus scope as the focusedChild of this node, adopting if it isn't already part of the focus tree.

Lifecycle

There are several actors involved in the lifecycle of a FocusNode/FocusScopeNode. They are created and disposed by their owner, attached, detached, and re-parented using a FocusAttachment by their host (which must be owned by the State of a StatefulWidget), and they are managed by the FocusManager. Different parts of the FocusNode API are intended for these different actors.

FocusNodes (and hence FocusScopeNodes) are persistent objects that form part of a focus tree that is a sparse representation of the widgets in the hierarchy that are interested in receiving keyboard events. They must be managed like other persistent state, which is typically done by a StatefulWidget that owns the node. A stateful widget that owns a focus scope node must call dispose from its State.dispose method.

Once created, a FocusNode must be attached to the widget tree via a FocusAttachment object. This attachment is created by calling attach, usually from the State.initState method. If the hosting widget is updated to have a different focus node, then the updated node needs to be attached in State.didUpdateWidget, after calling FocusAttachment.detach on the previous FocusAttachment.

Because FocusNodes form a sparse representation of the widget tree, they must be updated whenever the widget tree is rebuilt. This is done by calling FocusAttachment.reparent, usually from the State.build or State.didChangeDependencies methods of the widget that represents the focused region, so that the BuildContext assigned to the FocusScopeNode can be tracked (the context is used to obtain the RenderObject, from which the geometry of focused regions can be determined).

Creating a FocusNode each time State.build is invoked will cause the focus to be lost each time the widget is built, which is usually not desired behavior (call unfocus if losing focus is desired).

If, as is common, the hosting StatefulWidget is also the owner of the focus node, then it will also call dispose from its State.dispose (in which case the FocusAttachment.detach may be skipped, since dispose will automatically detach). If another object owns the focus node, then it must call dispose when the node is done being used.

Key Event Propagation

The FocusManager receives key events from RawKeyboard and HardwareKeyboard and will pass them to the focused nodes. It starts with the node with the primary focus, and will call the onKey or onKeyEvent callback for that node. If the callback returns KeyEventResult.ignored, indicating that it did not handle the event, the FocusManager will move to the parent of that node and call its onKey or onKeyEvent. If that onKey or onKeyEvent returns KeyEventResult.handled, then it will stop propagating the event. If it reaches the root FocusScopeNode, FocusManager.rootScope, the event is discarded.

See also:

  • Focus, a widget that manages a FocusNode and provides access to focus information and actions to its descendant widgets.
  • FocusManager, a singleton that manages the primary focus and distributes key events to focused nodes.
Inheritance

Constructors

FocusScopeNode({String? debugLabel, FocusOnKeyEventCallback? onKeyEvent, FocusOnKeyCallback? onKey, bool skipTraversal = false, bool canRequestFocus = true})
Creates a FocusScopeNode.

Properties

ancestors Iterable<FocusNode>
An Iterable over the ancestors of this node.
read-onlyinherited
canRequestFocus bool
If true, this focus node may request the primary focus.
mustCallSuper">@mustCallSuperread / writeinherited
children Iterable<FocusNode>
An iterator over the children of this node.
read-onlyinherited
context BuildContext?
The context that was supplied to attach.
read-onlyinherited
debugLabel String?
A debug label that is used for diagnostic output.
read / writeinherited
descendants Iterable<FocusNode>
An Iterable over the hierarchy of children below this one, in depth-first order.
read-onlyinherited
descendantsAreFocusable bool
If false, will disable focus for all of this node's descendants.
mustCallSuper">@mustCallSuperread / writeinherited
descendantsAreTraversable bool
If false, tells the focus traversal policy to skip over for all of this node's descendants for purposes of the traversal algorithm.
mustCallSuper">@mustCallSuperread / writeinherited
enclosingScope FocusScopeNode?
Returns the nearest enclosing scope node above this node, or null if the node has not yet be added to the focus tree.
read-onlyinherited
focusedChild FocusNode?
Returns the child of this node that should receive focus if this scope node receives focus.
read-only
hasFocus bool
Whether this node has input focus.
read-onlyinherited
hashCode int
The hash code for this object.
read-onlyinherited
hasListeners bool
Whether any listeners are currently registered.
protected">@protectedread-onlyinherited
hasPrimaryFocus bool
Returns true if this node currently has the application-wide input focus.
read-onlyinherited
highlightMode FocusHighlightMode
Returns the FocusHighlightMode that is currently in effect for this node.
read-onlyinherited
isFirstFocus bool
Returns true if this scope is the focused child of its parent scope.
read-only
nearestScope FocusScopeNode
Returns the nearest enclosing scope node above this node, including this node, if it's a scope.
read-onlyoverride
offset Offset
Returns the global offset to the upper left corner of the attached widget's RenderObject, in logical units.
read-onlyinherited
onKey FocusOnKeyCallback?
Called if this focus node receives a key event while focused (i.e. when hasFocus returns true).
read / writeinherited
onKeyEvent FocusOnKeyEventCallback?
Called if this focus node receives a key event while focused (i.e. when hasFocus returns true).
read / writeinherited
parent FocusNode?
Returns the parent node for this object.
read-onlyinherited
rect Rect
Returns the global rectangle of the attached widget's RenderObject, in logical units.
read-onlyinherited
runtimeType Type
A representation of the runtime type of the object.
read-onlyinherited
size Size
Returns the size of the attached widget's RenderObject, in logical units.
read-onlyinherited
skipTraversal bool
If true, tells the focus traversal policy to skip over this node for purposes of the traversal algorithm.
read / writeinherited
traversalChildren Iterable<FocusNode>
An iterator over the children that are allowed to be traversed by the FocusTraversalPolicy.
read-onlyoverride
traversalDescendants Iterable<FocusNode>
Returns all descendants which do not have the skipTraversal and do have the canRequestFocus flag set.
read-onlyoverride

Methods

addListener(VoidCallback listener) → void
Register a closure to be called when the object changes.
inherited
attach(BuildContext? context, {FocusOnKeyEventCallback? onKeyEvent, FocusOnKeyCallback? onKey}) FocusAttachment
Called by the host StatefulWidget to attach a FocusNode to the widget tree.
mustCallSuper">@mustCallSuperinherited
autofocus(FocusNode node) → void
If this scope lacks a focus, request that the given node become the focus.
consumeKeyboardToken() bool
Removes the keyboard token from this focus node if it has one.
inherited
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
override
dispose() → void
Discards any resources used by the object. After this is called, the object is not in a usable state and should be discarded (calls to addListener will throw after the object is disposed).
inherited
focusInDirection(TraversalDirection direction) bool
Request to move the focus to the nearest focus node in the given direction, by calling the FocusTraversalPolicy.inDirection method.
inherited
nextFocus() bool
Request to move the focus to the next focus node, by calling the FocusTraversalPolicy.next method.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed.
inherited
notifyListeners() → void
Call all the registered listeners.
protected">@protectedvisibleForTesting">@visibleForTestinginherited
previousFocus() bool
Request to move the focus to the previous focus node, by calling the FocusTraversalPolicy.previous method.
inherited
removeListener(VoidCallback listener) → void
Remove a previously registered closure from the list of closures that are notified when the object changes.
inherited
requestFocus([FocusNode? node]) → void
Requests the primary focus for this node, or for a supplied node, which will also give focus to its ancestors.
inherited
setFirstFocus(FocusScopeNode scope) → void
Make the given scope the active child scope for this scope.
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A brief description of this object, usually just the runtimeType and the hashCode.
inherited
unfocus({UnfocusDisposition disposition = UnfocusDisposition.scope}) → void
Removes the focus on this node by moving the primary focus to another node.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited