Add OrderedFocusTraversalPolicy and FocusTraversalGroup to allow focus traversal to follow a predefined order.#49235
Conversation
0cfc232 to
6a501fd
Compare
|
PTAL @redbrogdon |
|
nit: the analyzer is mad about some white space. |
6a501fd to
376deac
Compare
|
That analyzer is so picky, picky, picky! :-) (removed whitespace). |
efa4f69 to
3558ea6
Compare
|
From looking at the code it wasn't immediately clear to me if you could mix and match different policies. Let's say I am using a (third-party) widget that is internally managing FocusOrder via the lexical order and I want to use that widget in my app where I generally manage focus order with numerical order. Can I do that? How? Might be worthwhile to have a test. Same for different non-OrderedFocusTraversalPolicy in different subtrees. |
088c1ca to
096fb6f
Compare
|
The analyzer is complaining about a dependency loop. |
096fb6f to
04035f3
Compare
e172b4b to
077bc81
Compare
|
OK, @goderbauer, I think this is ready for another look. |
0416d99 to
922447a
Compare
|
I am still a little concerned about the performance implications of this. Ignoring that, this LGTM. |
|
Looks like Cirrus is unhappy now, though. |
…l… (flutter#49235)" This reverts commit 8ef5e2f because it breaks some semantics tests.
This re-lands #49235 with the addition of includeSemantics flag on the Focus widget so that the FocusTraversalGroup can create a Focus widget without affecting the semantics tree. The FocusTraversalGroup uses the Focus widget to create a grouping of descendants for traversal, but doesn't actually participate in focus (canRequestFocus is always false), so we don't want it to add a Semantics widget in that case, since that can cause semantics changes. The canRequestFocus attribute can also be used when a widget is disabled, so we do sometimes want to include Semantics even if that is false, but not in the case where it is always false, as for FocusTraversalGroup. - Added a test to make sure that FocusTraversalGroup doesn't add any semantics information.
Description
This change adds a way to provide explicit focus order for a part of the widget tree.
It adds
FocusTraversalPolicyGroup, which in many ways is similar toDefaultFocusTraversal, except that it groups a widget subtree together so that those nodes are traversed as a group.DefaultFocusTraversaldoesn't work as one would expect: If there is more than one DefaultFocusTraversal inside of a focus scope, the policy can change depending on which node was asked to move "next", which can cause unexpected behavior. The new grouping mechanism doesn't have that problem. I deprecateDefaultFocusTraversalin this PR.It adds
OrderedFocusTraversalPolicy, which is a policy that can be supplied toFocusTraversalPolicyGroupto set the policy for a sub-tree. It looks forFocusTraversalOrderinherited widgets, which use aFocusOrderto do the sorting.FocusOrderhas two subclasses:NumericalFocusOrder(which sorts based on a double), andLexicalFocusOrder, which sorts based on aString.As part of doing this, I refactored the way
FocusTraversalPolicyis implemented so that it has more default implementation methods, and exposes a new protected member:sortDescendants, which makes it easier for developers to make their own policy subclasses: they only need to implementsortDescendantsto get a new ordering behavior, but can also still override any of the default implementation behaviors if they need different behavior.I was able to do this without breaking the API (AFAICT).
Related Issues
Tests
*Orderclasses.Breaking Change