Skip to content

Commit 00ca7a8

Browse files
sganovAndroid (Google) Code Review
authored andcommitted
Merge "Accessibility focus traversal of lists inconsistent." into jb-dev
2 parents 561ff8a + 2dda468 commit 00ca7a8

File tree

1 file changed

+51
-49
lines changed

1 file changed

+51
-49
lines changed

core/java/android/widget/AbsListView.java

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
import android.view.ViewDebug;
5858
import android.view.ViewGroup;
5959
import android.view.ViewParent;
60-
import android.view.ViewRootImpl;
6160
import android.view.ViewTreeObserver;
6261
import android.view.accessibility.AccessibilityEvent;
6362
import android.view.accessibility.AccessibilityManager;
@@ -1331,43 +1330,42 @@ void invokeOnItemScrollListener() {
13311330

13321331
@Override
13331332
public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
1334-
if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY
1335-
&& (direction == ACCESSIBILITY_FOCUS_FORWARD
1336-
|| direction == ACCESSIBILITY_FOCUS_BACKWARD)) {
1337-
if (canTakeAccessibilityFocusFromHover()) {
1338-
views.add(this);
1333+
if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY) {
1334+
switch(direction) {
1335+
case ACCESSIBILITY_FOCUS_BACKWARD: {
1336+
View focusable = (getChildCount() > 0) ? getChildAt(getChildCount() - 1) : this;
1337+
if (focusable.canTakeAccessibilityFocusFromHover()) {
1338+
views.add(focusable);
1339+
}
1340+
} return;
1341+
case ACCESSIBILITY_FOCUS_FORWARD: {
1342+
if (canTakeAccessibilityFocusFromHover()) {
1343+
views.add(this);
1344+
}
1345+
} return;
13391346
}
1340-
} else {
13411347
super.addFocusables(views, direction, focusableMode);
13421348
}
13431349
}
13441350

13451351
@Override
13461352
public View focusSearch(int direction) {
1347-
return focusSearch(null, direction);
1353+
return focusSearch(this, direction);
13481354
}
13491355

13501356
@Override
13511357
public View focusSearch(View focused, int direction) {
13521358
switch (direction) {
13531359
case ACCESSIBILITY_FOCUS_FORWARD: {
1354-
ViewRootImpl viewRootImpl = getViewRootImpl();
1355-
if (viewRootImpl == null) {
1356-
return null;
1357-
}
1358-
View currentFocus = viewRootImpl.getAccessibilityFocusedHost();
1359-
if (currentFocus == null) {
1360-
return super.focusSearch(this, direction);
1361-
}
1362-
// If we have the focus try giving it to the first child.
1363-
if (currentFocus == this) {
1360+
// If we are the focused view try giving it to the first child.
1361+
if (focused == this) {
13641362
if (getChildCount() > 0) {
13651363
return getChildAt(0);
13661364
}
13671365
return super.focusSearch(this, direction);
13681366
}
1369-
// Find the item that has accessibility focus.
1370-
final int currentPosition = getPositionForView(currentFocus);
1367+
// Find the item that has the focused view.
1368+
final int currentPosition = getPositionForView(focused);
13711369
if (currentPosition < 0 || currentPosition >= getCount()) {
13721370
return super.focusSearch(this, direction);
13731371
}
@@ -1376,60 +1374,64 @@ public View focusSearch(View focused, int direction) {
13761374
if (currentItem instanceof ViewGroup) {
13771375
ViewGroup currentItemGroup = (ViewGroup) currentItem;
13781376
View nextFocus = FocusFinder.getInstance().findNextFocus(currentItemGroup,
1379-
currentFocus, direction);
1377+
focused, direction);
13801378
if (nextFocus != null && nextFocus != currentItemGroup
1381-
&& nextFocus != currentFocus) {
1379+
&& nextFocus != focused) {
13821380
return nextFocus;
13831381
}
13841382
}
13851383
// Try to move focus to the next item.
13861384
final int nextPosition = currentPosition - getFirstVisiblePosition() + 1;
13871385
if (nextPosition < getChildCount()) {
13881386
return getChildAt(nextPosition);
1389-
} else {
1390-
return super.focusSearch(this, direction);
13911387
}
1388+
// No next item start searching from the list.
1389+
return super.focusSearch(this, direction);
13921390
}
13931391
case ACCESSIBILITY_FOCUS_BACKWARD: {
1394-
ViewRootImpl viewRootImpl = getViewRootImpl();
1395-
if (viewRootImpl == null) {
1396-
return null;
1397-
}
1398-
View currentFocus = viewRootImpl.getAccessibilityFocusedHost();
1399-
if (currentFocus == null) {
1400-
return super.focusSearch(this, direction);
1401-
}
1402-
// If we have the focus do a generic search.
1403-
if (currentFocus == this) {
1404-
final int lastChildIndex = getChildCount() - 1;
1405-
if (lastChildIndex >= 0) {
1406-
return getChildAt(lastChildIndex);
1392+
// If we are the focused search from the view that is
1393+
// as closer to the bottom as possible.
1394+
if (focused == this) {
1395+
final int childCount = getChildCount();
1396+
if (childCount > 0) {
1397+
return super.focusSearch(getChildAt(childCount - 1), direction);
14071398
}
14081399
return super.focusSearch(this, direction);
14091400
}
1410-
// Find the item that has accessibility focus.
1411-
final int currentPosition = getPositionForView(currentFocus);
1401+
// Find the item that has the focused view.
1402+
final int currentPosition = getPositionForView(focused);
14121403
if (currentPosition < 0 || currentPosition >= getCount()) {
14131404
return super.focusSearch(this, direction);
14141405
}
1415-
// Try to advance focus in the current item.
1406+
14161407
View currentItem = getChildAt(currentPosition - getFirstVisiblePosition());
1408+
1409+
// If a list item is the focused view we try to find a view
1410+
// in the previous item since in reverse the item contents
1411+
// get accessibility focus before the item itself.
1412+
if (currentItem == focused) {
1413+
// This list gets accessibility focus after the last first item.
1414+
final int previoustPosition = currentPosition - getFirstVisiblePosition() - 1;
1415+
if (previoustPosition < 0) {
1416+
return this;
1417+
}
1418+
currentItem = getChildAt(previoustPosition);
1419+
focused = null;
1420+
}
1421+
1422+
// Search for into the item.
14171423
if (currentItem instanceof ViewGroup) {
14181424
ViewGroup currentItemGroup = (ViewGroup) currentItem;
14191425
View nextFocus = FocusFinder.getInstance().findNextFocus(currentItemGroup,
1420-
currentFocus, direction);
1426+
focused, direction);
14211427
if (nextFocus != null && nextFocus != currentItemGroup
1422-
&& nextFocus != currentFocus) {
1428+
&& nextFocus != focused) {
14231429
return nextFocus;
14241430
}
14251431
}
1426-
// Try to move focus to the previous item.
1427-
final int nextPosition = currentPosition - getFirstVisiblePosition() - 1;
1428-
if (nextPosition >= 0) {
1429-
return getChildAt(nextPosition);
1430-
} else {
1431-
return super.focusSearch(this, direction);
1432-
}
1432+
1433+
// If not item content wants focus we give it to the item.
1434+
return currentItem;
14331435
}
14341436
}
14351437
return super.focusSearch(focused, direction);

0 commit comments

Comments
 (0)