FocusScopeNode class
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 HardwareKeyboard and will pass them to the focused nodes. It starts with the node with the primary focus, and will call the 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 onKeyEvent. If that 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.
Constructors
- FocusScopeNode({String? debugLabel, FocusOnKeyEventCallback? onKeyEvent, @Deprecated('Use onKeyEvent instead. ' 'This feature was deprecated after v3.18.0-2.0.pre.') FocusOnKeyCallback? onKey, bool skipTraversal = false, bool canRequestFocus = true, TraversalEdgeBehavior traversalEdgeBehavior = TraversalEdgeBehavior.closedLoop})
- Creates a FocusScopeNode.
Properties
-
ancestors
→ Iterable<
FocusNode> -
An Iterable over the ancestors of this node.
no setterinherited
- canRequestFocus ↔ bool
-
If true, this focus node may request the primary focus.
getter/setter pairinherited
-
children
→ Iterable<
FocusNode> -
An iterator over the children of this node.
no setterinherited
- context → BuildContext?
-
The context that was supplied to attach.
no setterinherited
- debugLabel ↔ String?
-
A debug label that is used for diagnostic output.
getter/setter pairinherited
-
descendants
→ Iterable<
FocusNode> -
An Iterable over the hierarchy of children below this one, in
depth-first order.
no setterinherited
- descendantsAreFocusable ↔ bool
-
If false, will disable focus for all of this node's descendants.
getter/setter pairinherited-setteroverride-getter
- 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.
getter/setter pairinherited
- 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.
no setterinherited
- focusedChild → FocusNode?
-
Returns the child of this node that should receive focus if this scope
node receives focus.
no setter
- hasFocus → bool
-
Whether this node has input focus.
no setterinherited
- hashCode → int
-
The hash code for this object.
no setterinherited
- hasListeners → bool
-
Whether any listeners are currently registered.
no setterinherited
- hasPrimaryFocus → bool
-
Returns true if this node currently has the application-wide input focus.
no setterinherited
- highlightMode → FocusHighlightMode
-
Returns the FocusHighlightMode that is currently in effect for this node.
no setterinherited
- isFirstFocus → bool
-
Returns true if this scope is the focused child of its parent scope.
no setter
- nearestScope → FocusScopeNode
-
Returns the nearest enclosing scope node above this node, including
this node, if it's a scope.
no setteroverride
- offset → Offset
-
Returns the global offset to the upper left corner of the attached
widget's RenderObject, in logical units.
no setterinherited
- onKey ↔ FocusOnKeyCallback?
-
Called if this focus node receives a key event while focused (i.e. when
hasFocus returns true).
getter/setter pairinherited
- onKeyEvent ↔ FocusOnKeyEventCallback?
-
Called if this focus node receives a key event while focused (i.e. when
hasFocus returns true).
getter/setter pairinherited
- parent → FocusNode?
-
Returns the parent node for this object.
no setterinherited
- rect → Rect
-
Returns the global rectangle of the attached widget's RenderObject, in
logical units.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- size → Size
-
Returns the size of the attached widget's RenderObject, in logical
units.
no setterinherited
- skipTraversal ↔ bool
-
If true, tells the focus traversal policy to skip over this node for
purposes of the traversal algorithm.
getter/setter pairinherited
-
traversalChildren
→ Iterable<
FocusNode> -
An iterator over the children that are allowed to be traversed by the
FocusTraversalPolicy.
no setteroverride
-
traversalDescendants
→ Iterable<
FocusNode> -
Returns all descendants which do not have the skipTraversal and do have
the canRequestFocus flag set.
no setteroverride
- traversalEdgeBehavior ↔ TraversalEdgeBehavior
-
Controls the transfer of focus beyond the first and the last items of a
FocusScopeNode.
getter/setter pair
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.
inherited
-
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 nonexistent method or property is accessed.
inherited
-
notifyListeners(
) → void -
Call all the registered listeners.
inherited
-
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 -
requestScopeFocus(
) → void - Requests that the scope itself receive focus, without trying to find a descendant that should receive focus.
-
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, int wrapWidth = 65}) → 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