Android TabHost tabs steal focus when using Hardware Keyboard
Asked Answered
I

3

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?

Inappreciative answered 27/3, 2013 at 20:49 Comment(3)
Did you try this workaround? code.google.com/p/android/issues/detail?id=2516#c17Papeete
Were you able to sort it out? I'm having similar issue. Wondering if you found something.Gaidano
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.Inappreciative
T
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
Trumpetweed answered 4/4, 2013 at 12:39 Comment(4)
The TabHost still steals focus when I enter text on a Fragment that contains a TextView with that code.Unbroken
Added another example you could try.Trumpetweed
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.Unbroken
This does not fix the issue, instead it prevents tabs changing content when switching. So from my perspective this breaks more than it fixes.Sidestep
B
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".

Brumbaugh answered 2/10, 2015 at 21:28 Comment(1)
Slick fix, thanks!.. You could also subclass TabHost and implement this inteface there (in monodroid) public class MyTabHost : TabHost, View.IOnAttachStateChangeListener {...}Okajima
M
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

Micropathology answered 11/4, 2013 at 8:12 Comment(1)
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.Sidestep

© 2022 - 2024 — McMap. All rights reserved.