When a soft keyboard appears, this makes the EditText field lose focus

I have several EditText fields in a ListView. When I click on one of the EditText fields, the keyboard slides in the view (as it should), but the EditText field that I used loses focus. I tried using various InputMethodManager methods to get the keyboard to work (to get around the problem and not really solve it), but it didn’t work - the keyboard was not visible when Activity appeared.

The type is EditText number , and when the keyboard shifts, it is a numeric keypad, but when it ends crawling and EditText loses focus, it changes to an alphabetic keyboard (which reinforces the idea that EditText no longer has focus).

My questions are as follows:

1) How can I make a selection from my EditText field and then slide in the soft keyboard so that my EditText does not lose focus?

... otherwise...

2) How can I get the keyboard to start working, so it never needs to slide (thus avoiding the behavior that I find so undesirable)?

My manifest includes android:windowSoftInputMode="stateAlwaysVisible" , but the keyboard does not appear until I touch EditText. This ignoring the attribute "stateAlwaysVisible", apparently, occurs only in the emulator - on my prepared device, it is an honor, so question number 2 above works on the device ... but not in the emulator.

Thanks for any help you can provide!

+51
android android-emulator android-edittext
Apr 10 '11 at 23:28
source share
10 answers

Here is how I did it. onFocusChangeListener() is called several times when you touch EditText to print text. Sequence:

  • If the focus was on a different view, then that view loses focus
  • Focus target
  • A soft keyboard will appear.
  • This causes the target to lose focus.
  • The code detects this situation and calls target.requestFocus ()
  • The leftmost, topmost view gets focus, due to Android bullshit.
  • The leftmost view loses focus due to the fact that requestFocus is called
  • Target gets focus

     ////////////////////////////////////////////////////////////////// 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(); } }); } } } }; 

The code above works well for keyboard popups. However, it does not detect a speech-to-text popup.

+13
Mar 18 '14 at 4:13
source share

You need to change your AndroidManifest.xml

Add android: windowSoftInputMode = "adjustPan" to the action containing the listview. This will solve your problem.

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

Hello

+120
Nov 01 '11 at 10:37
source share

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

Since EditText is in the layout I am returning from getView (), this means that it is a different instance of EditText than the one that previously had focus. The second corollary is that when the soft keyboard appears or disappears, I find that I am losing the contents of the EditText.

Because I wanted my view to remain fully accessible (i.e. I want it to be changed, not hidden behind the keyboard window, and some parts not available), I could not use Frank's answer, which otherwise seems the best.

I solved this using OnFocusChangeListener in EditText to write the timestamp when the focus was lost, and then in getView () when recreating the list item, if the current time is within some threshold when the focus was lost, call requestFocus () to return it to the EditText in question.

You can also grab text from a previous EditText instance at this point and transfer it to a 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(); } } 
+9
Oct 24 '13 at 15:39
source share

You should check this code on a device that always has a hardware keyboard. This can also happen here.

To avoid this, you can always see the keyboard .. but it is not as easy as you can see on this topic:

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

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

+1
May 11 '11 at 15:27
source share

In AndroidManifest.xml, use adjustNothing in an activity containing views

 <activity android:name=".ActivityName" android:windowSoftInputMode="adjustNothing"> 
+1
Apr 28 '17 at 19:09 on
source share

If the editText is inside a listView, just make sure you have inflated the View in the getView method this way.




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



Edit: this work for some mobile phones is not all, I use the answer from Mr. Frank above.

+1
Jan 19 '18 at 17:07
source share

This guy had the same problem and more than that. He solved this using ScrollView and LinearLayout instead of ListView.

0
May 13 '11 at 9:01
source share

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

 <activity android:name=".MainActivity" android:windowSoftInputMode="adjustResize"> </activity> 
0
Mar 02 '17 at 11:05
source share

For those who come here with Xamarin or Xamarin.Forms:

I had the same problem, but only with Android 5.x - all new versions, including 8.1, worked well.

Shelton was obviously right in saying:

In my case, this is because when the ListView is resized, it re-creates all the list items (that is, it calls getView () again for each visible list item).

My browsing of the list is also windowSoftInputMode="adjustPan" and not, Frank's decision to set windowSoftInputMode="adjustPan" was an option for me, because it means that the keyboard partially moves the list view off the screen.

All I had to do after hours of debugging the focus was to set the cell caching strategy in the Xamarin Forms ListView:

From

 CachingStrategy="RecycleElement" 

to

 CachingStrategy="RetainElement" 

This will stop the cells from being recreated. However, this can lead to performance degradation and large memory consumption for huge lists. Be aware of

0
May 18 '18 at 9:36
source share

In my case, I called root_scrollview.fullScroll(View.FOCUS_DOWN) in my root ScrollView when the keyboard appeared. I replaced it

 login_scrollview.post(new Runnable() { @Override public void run() { root_scrollview.scrollTo(0,root_container.bottom) } }); 

where root_container is the immediate descendant of root_scrollview. This solved the problem for me.

Note. Direct calling root_scrollview.scrollTo(0,root_container.bottom) did not work.

0
Jul 05 '19 at 7:14
source share



All Articles