的EditText和TabHost不喜欢对方 [英] EditText and TabHost do not like each other

查看:113
本文介绍了的EditText和TabHost不喜欢对方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个EditText上和TabHost含2片布局。 Android 1.6的。

我在下列情况下使用硬件键盘。重现步骤:

  1. 在活动显示的EditText获得焦点。

  2. 当我preSS任意键的EditText失去焦点,并第一个选项卡获得它。

  3. 我再次点击的EditText并开始输入。

  4. 它的工作,除非我preSS任何数字按钮。第一个选项卡再次获得关注的焦点。

  5. 我滚动回用的EditText轨迹球。我现在可以输入任何东西。

使用轨迹球左/右上集中的EditText步骤2,3也使得EditText上失去重点。

这是非常奇怪的。如何处理这个吗?

main.xml中的布局:

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =FILL_PARENT机器人:layout_height =FILL_PARENT
    机器人:方向=垂直>

    < EditText上机器人:ID =@ + ID /文本框机器人:layout_width =FILL_PARENT
        机器人:layout_height =WRAP_CONTENT机器人:MAXLINES =1
        机器人:行=1机器人:提示=搜索/>

    < TabHost机器人:ID =@机器人:ID / tabhost机器人:layout_width =FILL_PARENT
        机器人:layout_height =WRAP_CONTENT机器人:layout_weight =1>

        <的LinearLayout机器人:方向=垂直
            机器人:layout_width =FILL_PARENT机器人:layout_height =FILL_PARENT>


            <的FrameLayout机器人:ID =@机器人:ID / tabcontent
                机器人:layout_width =FILL_PARENT机器人:layout_height =WRAP_CONTENT
                机器人:layout_weight =1>

                <的LinearLayout机器人:ID =@ + ID / TAB1
                    机器人:layout_width =FILL_PARENT机器人:layout_height =WRAP_CONTENT/>

                <的LinearLayout机器人:ID =@ + ID / TAB2
                    机器人:layout_width =FILL_PARENT机器人:layout_height =WRAP_CONTENT/>

            < /的FrameLayout>

            < TabWidget机器人:ID =@机器人:ID /标签
                机器人:方向=垂直机器人:layout_width =FILL_PARENT
                机器人:layout_height =WRAP_CONTENT安卓重力=底部/>

        < / LinearLayout中>

    < / TabHost>

< / LinearLayout中>
 

活动类:

  @覆盖
  公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);
    TabHost标签=(TabHost)this.findViewById(android.R.id.tabhost);
    tabs.setup();

    按钮vBtn;

    则tabspec tspec1 = tabs.newTabSpec(标一);
    vBtn =新的按钮(这一点);
    vBtn.setText(1);
    tspec1.setIndicator(vBtn);
    tspec1.setContent(R.id.tab1);

    则tabspec tspec2 = tabs.newTabSpec(标二);
    vBtn =新的按钮(这一点);
    vBtn.setText(2);
    tspec2.setIndicator(vBtn);
    tspec2.setContent(R.id.tab1);

    tabs.addTab(tspec1);
    tabs.addTab(tspec2);
  }
 

解决方案

通过Android源广泛挖掘后,我发现了错误: TabHost 注册一个OnTouchModeChangeListener在 onAttachedToWindow()的抢断时留下联系方式(又名当有人presses的关键)。集中

我已经创建了一个解决方法:只要把这个在的src /信息/ staticfree /解决方法/ TabPatchView.java 这个视图添加到您的布局,您使用的标签。请参阅下面的Javadoc获得更多信息。

 包info.staticfree.workarounds;

进口android.content.Context;
进口android.util.AttributeSet;
进口android.view.View;
进口android.widget.TabHost;

/ **
 *所述p为H.;
 *这是在使用选项卡的解决方法在Android的一个bug使得所有的内容
 *布局没有在翼片使TabHost从选项卡之外的任何次窃取焦点
 * 内容。这是最常见的EditTexts发现。
 *所述; / P>
 *所述p为H.;
 *使用时,只需将这个观点在@android:ID / tablayout frameview:
 *所述; / P>
 *
 *< pre>
 *< code取代;
 *放大器; LT;的FrameLayout
 *机器人:ID =@机器人:ID / tabcontent
 *机器人:layout_width =match_parent
 *机器人:layout_height =match_parent>
 *
 *放大器; LT; info.staticfree.workarounds.TabPatchView
 *机器人:layout_width =0dip
 *机器人:layout_height =0dip/>
 *
 * [您的实际内容放在这里]
 *放大器; LT; /的FrameLayout>
 *
 *< / pre>
 *
 *< / code取代;
 *
 * @author&所述; A HREF =电子邮件地址:steve@staticfree.info>史蒂夫波默罗伊&所述; / a取代;
 * @see&所述; A HREF =的http://$c$c.google.com/p/android/issues/detail的id = 2516>发行2516&所述; / a取代;
 * /
公共类TabPatchView扩展视图{

    公共TabPatchView(上下文的背景下){
        超(上下文);
    }

    公共TabPatchView(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
    }

    公共TabPatchView(上下文的背景下,ATTRS的AttributeSet,诠释defStyle){
        超(背景下,ATTRS,defStyle);
    }

    @覆盖
    保护无效onAttachedToWindow(){
        super.onAttachedToWindow();
        最后TabHost tabhost =(TabHost)getRootView()findViewById(android.R.id.tabhost)。
        。tabhost.getViewTreeObserver()removeOnTouchModeChangeListener(tabhost);
    }
}
 

如果您的目标SDK 12+,你可以使用 OnAttachStateChangeListener 代替。在的onCreate(),地址:

  TabHost mTab​​Host =(TabHost)findViewById(android.R.id.tabhost);
mTabHost.addOnAttachStateChangeListener(新OnAttachStateChangeListener(){

    @覆盖
    公共无效onViewDetachedFromWindow(视图v){}

    @覆盖
    公共无效onViewAttachedToWindow(视图v){
        。mTabHost.getViewTreeObserver()removeOnTouchModeChangeListener(mTabHost);
    }
});
 

这就是它!

I have a layout with EditText and TabHost containing 2 tabs. Android 1.6.

I use hardware keyboard in following case. Steps to reproduce:

  1. When activity is displayed the EditText gains focus.

  2. As soon as I press any key the EditText loses focus and first tab gains it.

  3. I click on the EditText again and start typing.

  4. It works unless I press any numeric button. The first tab gains the focus again.

  5. 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);
  }

解决方案

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;

/**
 * <p>
 * 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.
 * </p>
 * <p>
 * To use, simply place this view in your @android:id/tablayout frameview:
 * </p>
 * 
 * <pre>
 * <code>
 *             &lt;FrameLayout
 *                 android:id="@android:id/tabcontent"
 *                 android:layout_width="match_parent"
 *                 android:layout_height="match_parent" >
 * 
 *                 &lt;info.staticfree.workarounds.TabPatchView
 *                     android:layout_width="0dip"
 *                     android:layout_height="0dip" />
 *                     
 *                     [your actual content goes here]
 *                     &lt;/FrameLayout>
 * 
 * </pre>
 * 
 * </code>
 * 
 * @author <a href="mailto:steve@staticfree.info">Steve Pomeroy</a>
 * @see <a href="http://code.google.com/p/android/issues/detail?id=2516">issue 2516</a>
 */
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!

这篇关于的EditText和TabHost不喜欢对方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆