Spatial navigation (i.e. navigating around the UI via 5-point navigation) is handled for you by the framework if you make use of the VerticalList, HorizontalList and Grid widgets (or subclasses of them such as HorizontalCarousel).
Events that are not consumed bubble up through the Widget tree (not the DOM), until a higher-level widget can consume them. By nesting both Vertical and Horizontal lists within each other, you can build up a complex UI.
For more details about events, please see the Events section.
When discussing spatial navigation it is important to understand the notion of a widget’s active child.
This can be described as the following UI graph:
VerticalList |-- HorizontalList | |-- Button1 | |-- Button2 |--Button3
The focus/active state will be:
VerticalList (root, active, focused) |-- HorizontalList | |-- Button1 (active) | |-- Button2 |--Button3 (active, focused)
By default the first child appended to a widget that is focusable (i.e. has a descendant widget that is an enabled button) will become the active child.
When UP is pressed, the KeyEvent is bubbled from the focused Button,
Button3 up through the tree. In this case, the event will be consumed by
VerticalList, which can change it’s active child to the first item,
VerticalList (root, active, focused) |-- HorizontalList (active) | |-- Button1 (active) | |-- Button2 |--Button3
At this point the framework detects that there is a path of active widgets from the root, to a leaf Button,
Button1. It then sets the focus state on all widgets in this path:
VerticalList (root, active, focused) |-- HorizontalList (active, focused) | |-- Button1 (active, focused) | |-- Button2 |--Button3
i.e. focus state always moves to the active child. The UI will now look like: