Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
c4345d2a
Unverified
Commit
c4345d2a
authored
Feb 23, 2020
by
Greg Spencer
Committed by
GitHub
Feb 23, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a sample for FocusTraversalGroup (#51161)
parent
6d4121c0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
164 additions
and
14 deletions
+164
-14
focus_scope.dart
packages/flutter/lib/src/widgets/focus_scope.dart
+14
-14
focus_traversal.dart
packages/flutter/lib/src/widgets/focus_traversal.dart
+150
-0
No files found.
packages/flutter/lib/src/widgets/focus_scope.dart
View file @
c4345d2a
...
@@ -422,12 +422,12 @@ class Focus extends StatefulWidget {
...
@@ -422,12 +422,12 @@ class Focus extends StatefulWidget {
if
(
node
==
null
)
{
if
(
node
==
null
)
{
if
(!
nullOk
)
{
if
(!
nullOk
)
{
throw
FlutterError
(
throw
FlutterError
(
'Focus.of() was called with a context that does not contain a Focus widget.
\n
'
'Focus.of() was called with a context that does not contain a Focus widget.
\n
'
'No Focus widget ancestor could be found starting from the context that was passed to '
'No Focus widget ancestor could be found starting from the context that was passed to '
'Focus.of(). This can happen because you are using a widget that looks for a Focus '
'Focus.of(). This can happen because you are using a widget that looks for a Focus '
'ancestor, and do not have a Focus widget descendant in the nearest FocusScope.
\n
'
'ancestor, and do not have a Focus widget descendant in the nearest FocusScope.
\n
'
'The context used was:
\n
'
'The context used was:
\n
'
'
$context
'
'
$context
'
);
);
}
}
return
null
;
return
null
;
...
@@ -435,14 +435,14 @@ class Focus extends StatefulWidget {
...
@@ -435,14 +435,14 @@ class Focus extends StatefulWidget {
if
(!
scopeOk
&&
node
is
FocusScopeNode
)
{
if
(!
scopeOk
&&
node
is
FocusScopeNode
)
{
if
(!
nullOk
)
{
if
(!
nullOk
)
{
throw
FlutterError
(
throw
FlutterError
(
'Focus.of() was called with a context that does not contain a Focus between the given '
'Focus.of() was called with a context that does not contain a Focus between the given '
'context and the nearest FocusScope widget.
\n
'
'context and the nearest FocusScope widget.
\n
'
'No Focus ancestor could be found starting from the context that was passed to '
'No Focus ancestor could be found starting from the context that was passed to '
'Focus.of() to the point where it found the nearest FocusScope widget. This can happen '
'Focus.of() to the point where it found the nearest FocusScope widget. This can happen '
'because you are using a widget that looks for a Focus ancestor, and do not have a '
'because you are using a widget that looks for a Focus ancestor, and do not have a '
'Focus widget ancestor in the current FocusScope.
\n
'
'Focus widget ancestor in the current FocusScope.
\n
'
'The context used was:
\n
'
'The context used was:
\n
'
'
$context
'
'
$context
'
);
);
}
}
return
null
;
return
null
;
...
...
packages/flutter/lib/src/widgets/focus_traversal.dart
View file @
c4345d2a
...
@@ -1420,6 +1420,156 @@ class FocusTraversalOrder extends InheritedWidget {
...
@@ -1420,6 +1420,156 @@ class FocusTraversalOrder extends InheritedWidget {
///
///
/// By default, traverses in reading order using [ReadingOrderTraversalPolicy].
/// By default, traverses in reading order using [ReadingOrderTraversalPolicy].
///
///
/// {@tool dartpad --template=stateless_widget_material}
/// This sample shows three rows of buttons, each grouped by a
/// [FocusTraversalGroup], each with different traversal order policies. Use tab
/// traversal to see the order they are traversed in. The first row follows a
/// numerical order, the second follows a lexical order (ordered to traverse
/// right to left), and the third ignores the numerical order assigned to it and
/// traverses in widget order.
///
/// ```dart preamble
/// /// A button wrapper that adds either a numerical or lexical order, depending on
/// /// the type of T.
/// class OrderedButton<T> extends StatefulWidget {
/// const OrderedButton({
/// this.name,
/// this.canRequestFocus = true,
/// this.autofocus = false,
/// this.order,
/// });
///
/// final String name;
/// final bool canRequestFocus;
/// final bool autofocus;
/// final T order;
///
/// @override
/// _OrderedButtonState createState() => _OrderedButtonState();
/// }
///
/// class _OrderedButtonState<T> extends State<OrderedButton<T>> {
/// FocusNode focusNode;
///
/// @override
/// void initState() {
/// super.initState();
/// focusNode = FocusNode(
/// debugLabel: widget.name,
/// canRequestFocus: widget.canRequestFocus,
/// );
/// }
///
/// @override
/// void dispose() {
/// focusNode?.dispose();
/// super.dispose();
/// }
///
/// @override
/// void didUpdateWidget(OrderedButton oldWidget) {
/// super.didUpdateWidget(oldWidget);
/// focusNode.canRequestFocus = widget.canRequestFocus;
/// }
///
/// void _handleOnPressed() {
/// focusNode.requestFocus();
/// print('Button ${widget.name} pressed.');
/// debugDumpFocusTree();
/// }
///
/// @override
/// Widget build(BuildContext context) {
/// FocusOrder order;
/// if (widget.order is num) {
/// order = NumericFocusOrder((widget.order as num).toDouble());
/// } else {
/// order = LexicalFocusOrder(widget.order.toString());
/// }
///
/// return FocusTraversalOrder(
/// order: order,
/// child: Padding(
/// padding: const EdgeInsets.all(8.0),
/// child: OutlineButton(
/// focusNode: focusNode,
/// autofocus: widget.autofocus,
/// focusColor: Colors.red,
/// hoverColor: Colors.blue,
/// onPressed: () => _handleOnPressed(),
/// child: Text(widget.name),
/// ),
/// ),
/// );
/// }
/// }
/// ```
///
/// ```dart
/// Widget build(BuildContext context) {
/// return Container(
/// color: Colors.white,
/// child: FocusTraversalGroup(
/// policy: OrderedTraversalPolicy(),
/// child: Column(
/// mainAxisAlignment: MainAxisAlignment.center,
/// children: <Widget>[
/// // A group that is ordered with a numerical order, from left to right.
/// FocusTraversalGroup(
/// policy: OrderedTraversalPolicy(),
/// child: Row(
/// mainAxisAlignment: MainAxisAlignment.center,
/// children: List<Widget>.generate(3, (int index) {
/// return OrderedButton<num>(
/// name: 'num: $index',
/// // TRY THIS: change this to "3 - index" and see how the order changes.
/// order: index,
/// );
/// }),
/// ),
/// ),
/// // A group that is ordered with a lexical order, from right to left.
/// FocusTraversalGroup(
/// policy: OrderedTraversalPolicy(),
/// child: Row(
/// mainAxisAlignment: MainAxisAlignment.center,
/// children: List<Widget>.generate(3, (int index) {
/// // Order as "C" "B", "A".
/// String order =
/// String.fromCharCode('A'.codeUnitAt(0) + (2 - index));
/// return OrderedButton<String>(
/// name: 'String: $order',
/// order: order,
/// );
/// }),
/// ),
/// ),
/// // A group that orders in widget order, regardless of what the order is set to.
/// FocusTraversalGroup(
/// // Note that because this is NOT an OrderedTraversalPolicy, the
/// // assigned order of these OrderedButtons is ignored, and they
/// // are traversed in widget order. TRY THIS: change this to
/// // "OrderedTraversalPolicy()" and see that it now follows the
/// // numeric order set on them instead of the widget order.
/// policy: WidgetOrderTraversalPolicy(),
/// child: Row(
/// mainAxisAlignment: MainAxisAlignment.center,
/// children: List<Widget>.generate(3, (int index) {
/// return OrderedButton<num>(
/// name: 'ignored num: ${3 - index}',
/// order: 3 - index,
/// );
/// }),
/// ),
/// ),
/// ],
/// ),
/// ),
/// );
/// }
/// ```
/// {@end-tool}
///
/// See also:
/// See also:
///
///
/// * [FocusNode], for a description of the focus system.
/// * [FocusNode], for a description of the focus system.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment