当软键盘出现时,它会使我的EditText字段失去焦点

Kyl*_*eld 53 android android-emulator android-edittext

我在ListView中有一些EditText字段.当我点击其中一个EditText字段时,键盘会滑入视图(应该如此),但我点击的EditText字段会失去焦点.我已经尝试使用各种InputMethodManager方法使键盘在视图中启动(为了解决问题而不是真正解决它),但这不起作用 - 当Activity出现时键盘不在视图中.

EditText的类型是number,当键盘滑入时,它是一个数字键盘,但当它完成滑动并且EditText失去焦点时,它会变为字母键盘(这强化了EditText不再具有焦点的想法).

我的问题是这些:

1)如何选择我的EditText字段并随后滑入软键盘而不会使我的EditText失去焦点?

......失败了......

2)如何使键盘在视图中开始,以便它不必滑入(从而避免我发现这样令人反感的行为)?

我的清单包括android:windowSoftInputMode="stateAlwaysVisible",但直到我点击EditText键盘才出现.忽略'stateAlwaysVisible'属性似乎只出现在模拟器中 - 在我的配置设备上,它很荣幸,因此上面的问题2可以在设备上工作......但不在模拟器中.

感谢您的任何帮助,您可以提供!

Fra*_*ank 122

您需要更改AndroidManifest.xml

在持有listview的活动中添加android:windowSoftInputMode ="adjustPan".这将解决您的问题.

    <activity android:name=".MyEditTextInListView"
              android:label="@string/app_name"
              android:windowSoftInputMode="adjustPan">
Run Code Online (Sandbox Code Playgroud)

问候

  • 这应该是最好的答案. (19认同)
  • 嗯,它确实解决了焦点问题.但是,它有另一种效果,您可能会看到,视图不再调整大小. (10认同)
  • 是的,它不适用于三星s2 ......!你怎么解决的? (2认同)

Sol*_*lot 15

我就是这样做的.在onFocusChangeListener()当你触摸一个被称为多次EditText输入文本到它.顺序是:

  1. 如果焦点在不同的视图上,则该视图失去焦点
  2. 目标获得焦点
  3. 弹出软键盘.
  4. 这会导致目标失去焦点
  5. 代码检测到这种情况并调用target.requestFocus()
  6. 由于Android废话,最左边的最顶层视图获得了焦点
  7. 由于调用requestFocus,最左边的视图失去焦点
  8. 目标终于获得了关注

    //////////////////////////////////////////////////////////////////
    private final int minDelta = 300;           // threshold in ms
    private long focusTime = 0;                 // time of last touch
    private View focusTarget = null;
    
    View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean hasFocus) {
            long t = System.currentTimeMillis();
            long delta = t - focusTime;
            if (hasFocus) {     // gained focus
                if (delta > minDelta) {
                    focusTime = t;
                    focusTarget = view;
                }
            }
            else {              // lost focus
                if (delta <= minDelta  &&  view == focusTarget) {
                    focusTarget.post(new Runnable() {   // reset focus to target
                        public void run() {
                            focusTarget.requestFocus();
                        }
                    });
                }
            }
        }
    };
    
    Run Code Online (Sandbox Code Playgroud)

上面的代码适用于键盘弹出窗口.但是,它不会检测语音到文本弹出窗口.

  • 遗憾的是,Android 太糟糕了,以至于我们不得不为这种基本行为破解这些变通方法。感谢您的解决方案。 (4认同)

she*_*ond 10

在我的情况下,这种情况正在发生,因为当ListView调整大小时,它会重新创建所有列表项(即它为每个可见列表项再次调用getView()).

因为EditText在我从getView()返回的布局中,这意味着它是EditText的一个不同实例,而不是之前具有焦点的实例.第二个后果是,当软键盘出现或消失时,我发现我丢失了EditText的内容.

因为我希望我的视图保持完全可访问(即我希望它被调整大小而不是隐藏在键盘窗口后面,某些部分无法访问),我无法使用Frank的答案,否则这似乎是最好的方法.

我通过在EditText上使用OnFocusChangeListener来记录焦点丢失时的时间戳,然后在重新创建列表项时使用getView(),如果当前时间在焦点丢失时的某个阈值内,则调用requestFocus( )将它返回给有问题的EditText.

您还可以从该点的上一个EditText实例中获取文本并将其传输到新实例.

private class MyAdapter<Type> extends ArrayAdapter<String>
    implements OnFocusChangeListener
{
    private EditText mText;
    private long mTextLostFocusTimestamp;
    private LayoutInflater mLayoutInflater;

    public MyAdapter(Context context, int resource, int textResourceId, ArrayList<String> data, LayoutInflater li) {
        super(context, resource, textResourceId, data);
        mLayoutInflater = li;
        mTextLostFocusTimestamp = -1;
    }

    private void reclaimFocus(View v, long timestamp) {
        if (timestamp == -1)
            return;
        if ((System.currentTimeMillis() - timestamp) < 250)
            v.requestFocus();
    }

    @Override public View getView (int position, View convertView, ViewGroup parent)
    {
        View v = mLayoutInflater.inflate(R.layout.mylayout, parent, false);

        EditText newText = (EditText) v.findViewById(R.id.email);
        if (mText != null)
            newText.setText(mText.getText());
        mText = newText;
        mText.setOnFocusChangeListener(this);
        reclaimFocus(mText, mTextLostFocusTimestamp);

        return v;
    }

    @Override public void onFocusChange(View v, boolean hasFocus) {
        if ((v == mText) && !hasFocus)
            mTextLostFocusTimestamp = System.currentTimeMillis();
    }
}
Run Code Online (Sandbox Code Playgroud)