硬件键盘输入失去焦点

5

我在一个 TabHost 中有一个包含多个文本字段的片段。使用设置的 inputType,虚拟键盘可以正常输入文本,但是硬件键盘(在 Droid、Droid 2 等设备上)无法使用。

从我的测试来看,一旦你开始使用硬件键盘输入,EditText 就会失去焦点,而“打字”似乎会转移到应用程序中的其他地方。我尝试了下面两种配置:

<EditText
     android:id="@+id/editTextPlusFat"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_weight="0.15"
     android:background="@drawable/textfield_default_holo_light"
     android:digits="0123456789."
     android:ems="10"
     android:hint="@string/str_CalcHintFat"
     android:inputType="number" >

并且

<EditText
     android:id="@+id/editTextPlusFat"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_weight="0.15"
     android:background="@drawable/textfield_default_holo_light"
     android:ems="10"
     android:hint="@string/str_CalcHintFat"
     android:inputType="numberDecimal" >

有没有人有任何想法,为什么会发生这种情况?谢谢。


Related? - ioums
@ioums 看起来与我的问题非常相关,但并没有解决我的问题。我尝试了@Override onTouchModeChanged 方法,但它不起作用。我甚至尝试在方法内部放置一个 Toast.makeText(...) 来确保它被调用,但 Toast 在我的应用程序中从未出现过。 - mattdonders
另外一个需要注意的是,我尝试在EditText的onFocusChangeListener()内部调用getCurrentFocus()方法,结果TabHost会试图夺取焦点,然后程序运行出现了NullPointerException异常,并且日志中看到onTouchModeChanged()方法试图在TabHost上执行,但是扩展TabHost并覆盖该函数似乎不起作用。我已经在Fragment和Activity中尝试过这个方法。 - mattdonders
你能发布空指针吗? - DroidBender
2个回答

6

我的解决方案是在每个Fragment中的所有EditText上添加onTouchListener() - 如下所示。

OnTouchListener foucsHandler = new OnTouchListener() {
    @Override
    public boolean onTouch(View arg0, MotionEvent event) {
        // TODO Auto-generated method stub
        arg0.requestFocusFromTouch();
            return false;
    }
};

currentActivity.findViewById(R.id.editTextPlusServings).setOnTouchListener(foucsHandler);
currentActivity.findViewById(R.id.editTextPlusFoodName).setOnTouchListener(foucsHandler);

我在我的代码中也发现了这个问题。你有注意到任何副作用吗?换句话说,它对你仍然有效吗? 谢谢。 - copolii
是的,对我来说仍然有效。但有时候当我离开应用程序时,它会执行requestFocusFromTouch()例程并突出显示不同的应用程序图标,但这并不是每次都发生,而且老实说也不是很重要。 - mattdonders
太棒了。今天会试一下。谢谢。 - copolii
@mattdonders,很棒的解决方案,感谢分享。 - vinidog
@mattdonders,onTouchModeChanged()重写确实有效。所以不需要这个。请参见我的其他答案。 - pjv

6

如同重复问题中的回答,更好的解决方案是通过覆盖TabHost的onTouchModeChanged()函数来消除焦点切换。

添加一个新类并继承TabHost:

package net.lp.collectionista.ui.views;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.TabHost;

public class BugFixedTabHost extends TabHost {

    public BugFixedTabHost(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BugFixedTabHost(Context context) {
        super(context);
    }

    @Override
    public void onTouchModeChanged(boolean isInTouchMode) {
        // leave it empty here. It looks that when you use hard keyboard,
        // this method would have be called and the focus will be taken.
    }
}

在你的片段(或活动)中,将TabHost类型替换为BugFixedTabHost。

最后,假设您也在布局xmls中使用TabHost,请将其更改为您的自定义视图(完整包名称):

<net.lp.collectionista.ui.views.BugFixedTabHost
    android:id="@android:id/tabhost" ...

我不确定为什么这对@mattdonders没有起作用,但这是正确的方法。而且比将监听器附加到每个EditText更便宜。顺便问一句,我们已经弄清楚为什么mCurrentView.hasFocus()是False或者其他的原因了吗?

焦点问题有时会发生在将TabHost、软键盘、在一个WebView中打开的带有文本字段的HTML页面组合中。这个解决方案有效。 - Giulio Piancastelli
1
这个解决方案非常好。感谢分享(并且可以与Genymotion物理键盘一起使用)。 - Täg
是的,这是最佳解决方案。此外,看起来这个错误只存在于Lollipop版本之前。 - Nikolai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接