Android TabHost tabs steal focus when using Hardware Keyboard

扶醉桌前 提交于 2019-12-03 11:33:13

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!