11

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?

Mike Bailey
  • 12,479
  • 14
  • 66
  • 123
Michael Muesch
  • 173
  • 1
  • 5
  • Did you try this workaround? http://code.google.com/p/android/issues/detail?id=2516#c17 – Luis Apr 06 '13 at 15:18
  • Were you able to sort it out? I'm having similar issue. Wondering if you found something. – Renjith Apr 16 '13 at 09:31
  • We wound up just grabbing all input from the activity and disabling the enter button. We did not need it for anything else so it was not a big deal. Though it is not a proper solution. – Michael Muesch Apr 22 '13 at 18:29

3 Answers3

3

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
Leon Lucardie
  • 9,541
  • 4
  • 50
  • 70
  • The `TabHost` still steals focus when I enter text on a `Fragment` that contains a `TextView` with that code. – Mike Bailey Apr 04 '13 at 12:53
  • Added another example you could try. – Leon Lucardie Apr 04 '13 at 13:07
  • 1
    That seems to partially fix the issue. If you tap anywhere on the page that does not explicitly have a `View`, the old behavior arises again. – Mike Bailey Apr 04 '13 at 15:56
  • This does not fix the issue, instead it prevents tabs changing content when switching. So from my perspective this breaks more than it fixes. – ajeh Dec 19 '13 at 22:27
3

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".

Barry Fruitman
  • 12,316
  • 13
  • 72
  • 135
  • Slick fix, thanks!.. You could also subclass `TabHost` and implement this inteface there (in monodroid) `public class MyTabHost : TabHost, View.IOnAttachStateChangeListener {...}` – samus Feb 13 '17 at 21:31
1
 @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

Artem Zelinskiy
  • 2,201
  • 16
  • 19
  • This has strange effect: initially it looks like this is not working, but if I am typing lots into the edit, then at some point typing starts working as normal. It's enough to delete the typed characters for the tab host to steal focus again. W/o this fix typing very quickly sometimes works, but it does not have somewhat-permanent effect as with the fix. – ajeh Dec 19 '13 at 22:31