Skip to content

Commit 54ed87c

Browse files
Roger Olssonjredestig
authored andcommitted
TabHost key handling corrected
When receiving key presses in TabHost.java, focus should be requested for the selected tab indicator provided that the following conditions are fulfilled: 1) A content view inside an embedded activity is currently focused. 2) No focusable view exists in the direction of the navigation key press inside the embedded activity. 3) The TabWidget is located in the direction of the navigation key press. This should work for all locations of the TabWidget, not only when the TabWidget is located above the tab content. Change-Id: Ic5862cb72d2cc95aed9de92e42d6e0faf959fd43
1 parent 0748a56 commit 54ed87c

File tree

1 file changed

+63
-8
lines changed

1 file changed

+63
-8
lines changed

core/java/android/widget/TabHost.java

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
*/
4949
public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchModeChangeListener {
5050

51+
private static final int TABWIDGET_LOCATION_LEFT = 0;
52+
private static final int TABWIDGET_LOCATION_TOP = 1;
53+
private static final int TABWIDGET_LOCATION_RIGHT = 2;
54+
private static final int TABWIDGET_LOCATION_BOTTOM = 3;
5155
private TabWidget mTabWidget;
5256
private FrameLayout mTabContent;
5357
private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2);
@@ -293,22 +297,73 @@ public FrameLayout getTabContentView() {
293297
return mTabContent;
294298
}
295299

300+
/**
301+
* Get the location of the TabWidget.
302+
*
303+
* @return The TabWidget location.
304+
*/
305+
private int getTabWidgetLocation() {
306+
int location = TABWIDGET_LOCATION_TOP;
307+
308+
switch (mTabWidget.getOrientation()) {
309+
case LinearLayout.VERTICAL:
310+
location = (mTabContent.getLeft() < mTabWidget.getLeft()) ? TABWIDGET_LOCATION_RIGHT
311+
: TABWIDGET_LOCATION_LEFT;
312+
break;
313+
case LinearLayout.HORIZONTAL:
314+
default:
315+
location = (mTabContent.getTop() < mTabWidget.getTop()) ? TABWIDGET_LOCATION_BOTTOM
316+
: TABWIDGET_LOCATION_TOP;
317+
break;
318+
}
319+
return location;
320+
}
321+
296322
@Override
297323
public boolean dispatchKeyEvent(KeyEvent event) {
298324
final boolean handled = super.dispatchKeyEvent(event);
299325

300-
// unhandled key ups change focus to tab indicator for embedded activities
301-
// when there is nothing that will take focus from default focus searching
326+
// unhandled key events change focus to tab indicator for embedded
327+
// activities when there is nothing that will take focus from default
328+
// focus searching
302329
if (!handled
303330
&& (event.getAction() == KeyEvent.ACTION_DOWN)
304-
&& (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP)
305331
&& (mCurrentView != null)
306332
&& (mCurrentView.isRootNamespace())
307-
&& (mCurrentView.hasFocus())
308-
&& (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null)) {
309-
mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
310-
playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
311-
return true;
333+
&& (mCurrentView.hasFocus())) {
334+
int keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
335+
int directionShouldChangeFocus = View.FOCUS_UP;
336+
int soundEffect = SoundEffectConstants.NAVIGATION_UP;
337+
338+
switch (getTabWidgetLocation()) {
339+
case TABWIDGET_LOCATION_LEFT:
340+
keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_LEFT;
341+
directionShouldChangeFocus = View.FOCUS_LEFT;
342+
soundEffect = SoundEffectConstants.NAVIGATION_LEFT;
343+
break;
344+
case TABWIDGET_LOCATION_RIGHT:
345+
keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_RIGHT;
346+
directionShouldChangeFocus = View.FOCUS_RIGHT;
347+
soundEffect = SoundEffectConstants.NAVIGATION_RIGHT;
348+
break;
349+
case TABWIDGET_LOCATION_BOTTOM:
350+
keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_DOWN;
351+
directionShouldChangeFocus = View.FOCUS_DOWN;
352+
soundEffect = SoundEffectConstants.NAVIGATION_DOWN;
353+
break;
354+
case TABWIDGET_LOCATION_TOP:
355+
default:
356+
keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
357+
directionShouldChangeFocus = View.FOCUS_UP;
358+
soundEffect = SoundEffectConstants.NAVIGATION_UP;
359+
break;
360+
}
361+
if (event.getKeyCode() == keyCodeShouldChangeFocus
362+
&& mCurrentView.findFocus().focusSearch(directionShouldChangeFocus) == null) {
363+
mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
364+
playSoundEffect(soundEffect);
365+
return true;
366+
}
312367
}
313368
return handled;
314369
}

0 commit comments

Comments
 (0)