I currently have a TabHost
containing 4 tabs. On a few of the fragments we have a number of EditText
views within the layout.
We have noticed that when you attempt to type into any of the EditText
views using the hardware keyboard, the focus is stolen from the EditText
and given to the currently active tab in the TabHost
. This only occurs on screens with tabs. Is there a quick and simple way to solve this?
This has been a known bug for quite a long time:
http://code.google.com/p/android/issues/detail?id=2516
A workaround would be forcing the TabHost
to lose focus after a tab is selected.
This is done by setting a OnTabChangeListener
for the TabHost
and calling clearFocus
in the onTabChanged
method.
tabHost.setOnTabChangedListener(new OnTabChangeListener(){
public void onTabChanged(String tabID) {
tabHost.clearFocus();
}
});
EDIT: If this doesn't work you can try the other way around. Forcing the EditText fields to gain focus instead:
OnTouchListener focusHandler = new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
view.requestFocusFromTouch();
return false;
}
};
editText.setOnTouchListener(focusHandler); //For each EditText with this issue
I found this solution at http://code.google.com/p/android/issues/detail?id=2516 and it works better than any of the solutions here or on the bug report page, because it addresses the root cause instead of working around it. I'll let the author (g1adrift) explain:
After digging extensively through the Android source, I found the bug: TabHost registers an OnTouchModeChangeListener in onAttachedToWindow() that steals focus when leaving touch mode (aka when someone presses a key) if the current tab content view doesn't have focus. While this may make sense if the whole layout is tabbed, if there is only a portion of the layout that has tabs, it causes issues.
This workaround removes that listener, so all artifacts of using it should go away:
in onCreate(), add:
TabHost mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
public void onViewDetachedFromWindow(View v) {}
@Override
public void onViewAttachedToWindow(View v) {
mTabHost.getViewTreeObserver().removeOnTouchModeChangeListener(mTabHost);
}
});
It supposedly only works for SDK 12+. The author also posted a solution for earlier SDKs. If you need it, click the link above and search for posts by "g1adrift".
@Override
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
copy-paste from android support library examples
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With