diff options
| author | Vadim Tryshev <vadimt@google.com> | 2016-12-21 19:22:26 -0800 |
|---|---|---|
| committer | Vadim Tryshev <vadimt@google.com> | 2017-01-03 18:18:36 -0800 |
| commit | 8957f2ddda08e891475e64552ffa225ca2fccedb (patch) | |
| tree | 59edda77f107f6f992bcdd1f02c30d8ff8425696 /core/java/android/view/FocusFinder.java | |
| parent | 196bbe7a4b0640a62bd0595ce8b89b95817e8106 (diff) | |
Introducing teleportation between sections.
The key combos differ from the ones in the spec because key combos
including Meta key don’t get delivered to apps. To fix this, I’ll
implement necessary plumbing after the feature freeze. Meanwhile,
temporary combos are used.
Given that the section and cluster teleportation have a lot in common,
I’m not introducing new methods, but adding a param to the cluster
teleportation ones. I should have also changed the names to something
like findNextKeyboardNavigationCluster => findNextFocusGroup, where
“FocusGroup” is a generalized name for clusters and sections.
However, that name depends on b/33708251, so I’m not doing it now. I
don’t rename existing identifiers, and using “focusGroup” for new
ones. Admittedly, this creates mess that will be resolved based on
the outcome of the mentioned bug.
Bug: 32151632
Test: Manual checks; CTS are coming after feature freeze
Change-Id: I01b5d6e5a9689b8f643fa4af695d2ce61265f374
Diffstat (limited to 'core/java/android/view/FocusFinder.java')
| -rw-r--r-- | core/java/android/view/FocusFinder.java | 74 |
1 files changed, 57 insertions, 17 deletions
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java index 3f3d5190fac7..1a4f0d1ae803 100644 --- a/core/java/android/view/FocusFinder.java +++ b/core/java/android/view/FocusFinder.java @@ -16,12 +16,16 @@ package android.view; +import static android.view.View.FOCUS_GROUP_CLUSTER; +import static android.view.View.FOCUS_GROUP_SECTION; + import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import android.util.ArrayMap; import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.view.View.FocusGroupType; import java.util.ArrayList; import java.util.Collections; @@ -107,21 +111,26 @@ public class FocusFinder { /** * Find the root of the next keyboard navigation cluster after the current one. - * @param root Thew view tree to look inside. Cannot be null + * @param focusGroupType Type of the focus group + * @param root The view tree to look inside. Cannot be null * @param currentCluster The starting point of the search. Null means the default cluster * @param direction Direction to look * @return The next cluster, or null if none exists */ public View findNextKeyboardNavigationCluster( - @NonNull ViewGroup root, @Nullable View currentCluster, int direction) { + @FocusGroupType int focusGroupType, + @NonNull View root, + @Nullable View currentCluster, + int direction) { View next = null; final ArrayList<View> clusters = mTempList; try { clusters.clear(); - root.addKeyboardNavigationClusters(clusters, direction); + root.addKeyboardNavigationClusters(focusGroupType, clusters, direction); if (!clusters.isEmpty()) { - next = findNextKeyboardNavigationCluster(root, currentCluster, clusters, direction); + next = findNextKeyboardNavigationCluster( + focusGroupType, root, currentCluster, clusters, direction); } } finally { clusters.clear(); @@ -197,19 +206,25 @@ public class FocusFinder { } } - private View findNextKeyboardNavigationCluster(ViewGroup root, View currentCluster, - List<View> clusters, int direction) { + private View findNextKeyboardNavigationCluster( + @FocusGroupType int focusGroupType, + View root, + View currentCluster, + List<View> clusters, + int direction) { final int count = clusters.size(); switch (direction) { case View.FOCUS_FORWARD: case View.FOCUS_DOWN: case View.FOCUS_RIGHT: - return getNextKeyboardNavigationCluster(root, currentCluster, clusters, count); + return getNextKeyboardNavigationCluster( + focusGroupType, root, currentCluster, clusters, count); case View.FOCUS_BACKWARD: case View.FOCUS_UP: case View.FOCUS_LEFT: - return getPreviousKeyboardNavigationCluster(root, currentCluster, clusters, count); + return getPreviousKeyboardNavigationCluster( + focusGroupType, root, currentCluster, clusters, count); default: throw new IllegalArgumentException("Unknown direction: " + direction); } @@ -315,8 +330,12 @@ public class FocusFinder { return null; } - private static View getNextKeyboardNavigationCluster(ViewGroup root, View currentCluster, - List<View> clusters, int count) { + private static View getNextKeyboardNavigationCluster( + @FocusGroupType int focusGroupType, + View root, + View currentCluster, + List<View> clusters, + int count) { if (currentCluster == null) { // The current cluster is the default one. // The next cluster after the default one is the first one. @@ -330,12 +349,25 @@ public class FocusFinder { return clusters.get(position + 1); } - // The current cluster is the last one. The next one is the default one, i.e. the root. - return root; + switch (focusGroupType) { + case FOCUS_GROUP_CLUSTER: + // The current cluster is the last one. The next one is the default one, i.e. the + // root. + return root; + case FOCUS_GROUP_SECTION: + // There is no "default section", hence returning the first one. + return clusters.get(0); + default: + throw new IllegalArgumentException("Unknown focus group type: " + focusGroupType); + } } - private static View getPreviousKeyboardNavigationCluster(ViewGroup root, View currentCluster, - List<View> clusters, int count) { + private static View getPreviousKeyboardNavigationCluster( + @FocusGroupType int focusGroupType, + View root, + View currentCluster, + List<View> clusters, + int count) { if (currentCluster == null) { // The current cluster is the default one. // The previous cluster before the default one is the last one. @@ -349,9 +381,17 @@ public class FocusFinder { return clusters.get(position - 1); } - // The current cluster is the first one. The previous one is the default one, i.e. the - // root. - return root; + switch (focusGroupType) { + case FOCUS_GROUP_CLUSTER: + // The current cluster is the first one. The previous one is the default one, i.e. + // the root. + return root; + case FOCUS_GROUP_SECTION: + // There is no "default section", hence returning the last one. + return clusters.get(count - 1); + default: + throw new IllegalArgumentException("Unknown focus group type: " + focusGroupType); + } } /** |
