5757import android .view .ViewDebug ;
5858import android .view .ViewGroup ;
5959import android .view .ViewParent ;
60- import android .view .ViewRootImpl ;
6160import android .view .ViewTreeObserver ;
6261import android .view .accessibility .AccessibilityEvent ;
6362import 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