When the soft keyboard appears, it makes my EditTe

2019-01-16 03:17发布

I've got a few EditText fields in a ListView. When I tap on one of the EditText fields, the keyboard slides into view (as it should), but the EditText field I tapped loses focus. I've tried using various InputMethodManager methods to make the keyboard start out in view (in order to get around the problem rather than truly solve it), but that didn't work - the keyboard was not in view when the Activity appeared.

The EditText's type is number, and when the keyboard is sliding in, it is a number keyboard, but when it finishes sliding and the EditText loses focus, it changes to the alphabetical keyboard (which reinforces the idea that the EditText no longer has focus).

My questions are these:

1) How can I make the selection of my EditText field and the subsequent sliding in of the soft keyboard not make my EditText lose focus?

... failing that...

2) How can I make the keyboard start out in view so it never has to slide in (thus avoiding the behavior I find so objectionable)?

My manifest does include android:windowSoftInputMode="stateAlwaysVisible", but the keyboard does not appear until I tap on an EditText. This ignoring of the 'stateAlwaysVisible' attribute seems to only occur in the emulator - on my provisioned device, it is honored so question number 2 above does work on the device... but not in the emulator.

Thanks for any help you can provide!

9条回答
放荡不羁爱自由
2楼-- · 2019-01-16 03:52

If the editText inside the listView just make sure that you inflate the View in the getView method with this way.


        if (convertView == null)
        convertView = LayoutInflater.from(context).inflate(R.layout.yourItemListLayout,
                parent, false);   

Edit: this work for some mobiles not all I use the answer from Mr.Frank above.

查看更多
爷的心禁止访问
3楼-- · 2019-01-16 03:54

You need to change in your AndroidManifest.xml

Add android:windowSoftInputMode="adjustPan" in the activity holding the listview. This will solve your problem.

    <activity android:name=".MyEditTextInListView"
              android:label="@string/app_name"
              android:windowSoftInputMode="adjustPan">

Regards

查看更多
小情绪 Triste *
4楼-- · 2019-01-16 03:55

Add android:windowSoftInputMode="adjustResize" in the activity holding the listview or EditText. This will solve your problem.

<activity android:name=".MainActivity"
        android:windowSoftInputMode="adjustResize">
</activity>
查看更多
一纸荒年 Trace。
5楼-- · 2019-01-16 03:56

In my case, this is happening because when the ListView resizes, it re-creates all of the list items (i.e. it calls getView() again for each visible list item).

Because the EditText is within the layout that I'm returning from getView(), this means that it's a different instance of EditText than the one which had the focus previously. A secondary consequence is that when the soft-keyboard appears or disappears I found that I was losing the contents of the EditText.

Because I wanted my view to remain fully accessible (i.e. I want it to be resized instead of hidden behind the keyboard window with some parts not accessible), I couldn't use Frank's answer, which otherwise seems like the best approach.

I solved this by using an OnFocusChangeListener on the EditText to record the timestamp when the focus was lost, and then in getView() when recreating the list item, if the current time is within some threshold from when the focus was lost, call requestFocus() to give it back to the EditText in question.

You can also grab the text from the previous instance of the EditText at that point and transfer it to the new instance.

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();
    }
}
查看更多
贪生不怕死
6楼-- · 2019-01-16 04:03

You should test this code on a device with hardware keyboard always visible. The behavior may also happen here.

To avoid this you can have the keyboard always visible.. but that is not very easy as you can see by this thread:

https://groups.google.com/forum/#!topic/android-developers/FyENeEdmYC0

Theoretically you may have to create your own Android keyboard (although using as base the stock Android keyboard) as described here: Android: How to make the keypad always visible?

查看更多
相关推荐>>
7楼-- · 2019-01-16 04:03

This guy had the same problem and more besides. He solved it by using a ScrollView and a LinearLayout instead of a ListView.

查看更多
登录 后发表回答