I have a layout with EditText and TabHost containing 2 tabs. Android 1.6.
I use hardware keyboard in following case. Steps to reproduce:
When activity i
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).
I've created a workaround: just place this in src/info/staticfree/workarounds/TabPatchView.java
and add this view to your layout where you use tabs. See the Javadoc below for more details.
package info.staticfree.workarounds;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TabHost;
/**
*
* This is a workaround for a bug in Android in which using tabs such that all the content of the
* layout isn't in the tabs causes the TabHost to steal focus from any views outside the tab
* content. This is most commonly found with EditTexts.
*
*
* To use, simply place this view in your @android:id/tablayout frameview:
*
*
*
*
* <FrameLayout
* android:id="@android:id/tabcontent"
* android:layout_width="match_parent"
* android:layout_height="match_parent" >
*
* <info.staticfree.workarounds.TabPatchView
* android:layout_width="0dip"
* android:layout_height="0dip" />
*
* [your actual content goes here]
* </FrameLayout>
*
*
*
*
*
* @author Steve Pomeroy
* @see issue 2516
*/
public class TabPatchView extends View {
public TabPatchView(Context context) {
super(context);
}
public TabPatchView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TabPatchView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
final TabHost tabhost = (TabHost) getRootView().findViewById(android.R.id.tabhost);
tabhost.getViewTreeObserver().removeOnTouchModeChangeListener(tabhost);
}
}
If you're targeting SDK 12+, you can use OnAttachStateChangeListener
instead. 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);
}
});
And that's it!