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 is displayed the EditText gains focus.
As soon as I press any key the EditText loses focus and first tab gains it.
I click on the EditText again and start typing.
It works unless I press any numeric button. The first tab gains the focus again.
I scroll back to the EditText with track ball. I can type anything now.
Using track ball left/right on focused EditText in steps 2,3 also makes the EditText lose its focus.
This is very weird. How to handle with this?
main.xml layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<EditText android:id="@+id/textfield" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:maxLines="1"
android:lines="1" android:hint="Search" />
<TabHost android:id="@android:id/tabhost" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_weight="1">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout android:id="@+id/tab1"
android:layout_width="fill_parent" android:layout_height="wrap_content" />
<LinearLayout android:id="@+id/tab2"
android:layout_width="fill_parent" android:layout_height="wrap_content" />
</FrameLayout>
<TabWidget android:id="@android:id/tabs"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:gravity="bottom" />
</LinearLayout>
</TabHost>
</LinearLayout>
Activity class:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabs = (TabHost) this.findViewById(android.R.id.tabhost);
tabs.setup();
Button vBtn;
TabSpec tspec1 = tabs.newTabSpec("label one");
vBtn = new Button(this);
vBtn.setText("1");
tspec1.setIndicator(vBtn);
tspec1.setContent(R.id.tab1);
TabSpec tspec2 = tabs.newTabSpec("label two");
vBtn = new Button(this);
vBtn.setText("2");
tspec2.setIndicator(vBtn);
tspec2.setContent(R.id.tab1);
tabs.addTab(tspec1);
tabs.addTab(tspec2);
}
You really don't want to use TabHost and Tabwidget in the XML layout file to setup your tabs.
I did it all through code in a class that extends TabActivity, and for each tab, I just associated an Activity with its own XML Layout file that took care of the UI layout for that specific tab.
Here is the TabActivity class, and also an example of the background_selectors XML that takes care of the appearance of the TAB Label.
Here is the first_tab_background_selectors XML file:
The selected_tab_icon and the unselected_tab_icons are .PNG image files, following the size, resolution, and other graphics guidelines as instructed in the Android Developers Guide.
After digging extensively through the Android source, I found the bug:
TabHost
registers an OnTouchModeChangeListener inonAttachedToWindow()
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.If you're targeting SDK 12+, you can use
OnAttachStateChangeListener
instead. InonCreate()
, add:And that's it!