Android : keyboard show/hide with multiple EditText - android

I have an activity with a listview and each row has several editText. It looks like a questionnaire.
I have for example the focus on one EditText, then I click on another EditText. At the moment, the keyboard disappear and reappear. It is very irritating.
I use that code to make the keyboard disppear when the user click anywhere else on the activity when he don't want to type. But if the user click on another editText, I would like the keyboard stay.
Someone has an idea if the keyboard is already shown, how to keep it open when I click on a EditText?
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
View w = getCurrentFocus();
if (w instanceof EditText) {
int scrcoords[] = new int[2];
w.getLocationOnScreen(scrcoords);
float x = event.getRawX() + w.getLeft() - scrcoords[0];
float y = event.getRawY() + w.getTop() - scrcoords[1];
if (event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom()) ) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
}
}
return super.dispatchTouchEvent(event);
}

Make sure you're setting your android:inputType on your EditText declarations in XML. If this doesn't solve the issue by itself, you can specify next focuses using the View class's android:nextFocusUp, android:nextFocusDown, android:nextFocusRight, or android:nextFocusLeft to indicate the next EditText to move to.
Lastly, it could have something to do with how the ListView is handling focus. If that's the case, there's a related question here that would probably be worth looking at.

Would be helpful if you could share your code.
I think what is happening is that your listview is causing your edit text to lose focus when you tap another one on a different row.
In general, what you could do is to register on a focus change listener on your edit text and then every time your edit text loses focus you can run a function to display the keyboard again.
replyInputEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
showKeyboard(editText);
}
});
The showkeyboard function :
public void showKeyboard(EditText field){
field.setFocusable(true);
field.setFocusableInTouchMode(true);
field.requestFocus();
InputMethodManager imm = (InputMethodManager) activity.getSystemService(activity.getApplicationContext().INPUT_METHOD_SERVICE);
imm.showSoftInput(field, InputMethodManager.SHOW_IMPLICIT);
}
You could also register an ontouchup listener on the text fields and then calling the showKeyboard function.

Related

How to add a constant uneditable text at the end of editText android?

I am trying to implement a sign up screen, where I have two ediTexts inside two TextInputLayouts (one for email and one for password). However, for email, I want to have a constant text for the domain. Is there any way I could set the text to remain at the end of the editText or any better suggestion? Email here is the hint, I want the user to be able to type at the start only, with the #example.com remaining constant.
You can either try one of these:
1) In a horizontal LinearLayout, put your textInputLayout (width=wrap_content) and a textView (width=0dp & weight=1) containing the domain name. Whenever the email edittext receives focus, show the textview else hide it.
2) Add a text watcher to the edittext and onAfterTextChanged method add the domain name to the string. Here you have to check whether the edittext's string ends with the domain name or not... if not then only add the domain name else do not add it. Personally, this is not an elegant solution as cursor wont be at expected position after text changes.
Thanks
You can use this library ,i have worked
https://github.com/gotokatsuya/ParkedTextView
So here's the updated solution.
emailEditText.setText("#gmail.com");
emailEditText.setSelection(0);
emailEditText.requestFocus();
emailEditText.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
Layout layout = ((EditText) v).getLayout();
float x = event.getX() + emailEditText.getScrollX();
offset = layout.getOffsetForHorizontal(0, x);
maxOffset = emailEditText.getText().toString().indexOf("#");
break;
case MotionEvent.ACTION_UP:
if(offset > maxOffset && maxOffset >= 0) {
emailEditText.setSelection(maxOffset);
}
else if (offset >= 0) {
emailEditText.setSelection(offset);
}
event.setAction(MotionEvent.ACTION_CANCEL);
showSoftKeyBoard(emailEditText);
}
return false;
}
});
public void showSoftKeyBoard(View focusedView) {
if(getCurrentFocus() != null) {
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
.showSoftInput(focusedView, InputMethodManager.SHOW_IMPLICIT);
}
}
Finally a Disclaimer... you can move around the cursor but there is no holder that you usually see at the bottom of the cursor.

Close keypad when touch or click outside of EditText in Android

For closing the keypad when touches or clicks the outside of the Edittext, i followed the below code. if there is one edittext its working correctly but more than one its not working.
Example Scenario:
Step 1 : Clicking the first edittext it opens the keypad.
Step 2 : Clicking outside of the first edittext it closes the keypad.
Step 3 : Clicking the second edittext it doesn't open the keypad.
i think it consider second edittext as a outside of first edittext. i dont know really... can someone please help me...
and this code is for all edittext field in a activity we can use, we can do by using specific edittext also, but i don't want to find a outside clicks or touches of a specific edittext.
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
View view = getCurrentFocus();
boolean ret = super.dispatchTouchEvent(event);
if (view instanceof EditText) {
View w = getCurrentFocus();
int scrcoords[] = new int[2];
w.getLocationOnScreen(scrcoords);
float x = event.getRawX() + w.getLeft() - scrcoords[0];
float y = event.getRawY() + w.getTop() - scrcoords[1];
if (event.getAction() == MotionEvent.ACTION_UP
&& (x < w.getLeft() || x >= w.getRight()
|| y < w.getTop() || y > w.getBottom()) ) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
}
}
return ret;
}
Please try with following code:
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity
.getSystemService(Activity.INPUT_METHOD_SERVICE);
if (inputMethodManager.isAcceptingText()) {
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,
0);//You need to change the focus here to another view for hide the keyboard.
}
}
You need to call the above method as follows :
Here we are checking that if edittext object has focus then call below method.
if (etSeach.hasFocus()) {
hideSoftKeyboard(ViewTaskActivity.this);
}

android - show keyboard fix bottom framelayout

I am developing an android application in which my mainActivity has 5 tabs at the bottom represented in FrameLayout. Each tab points to a particular fragment which gets loaded based on the tab clicked.
In my 1st tab, I've an EditText. When the edit text is focused, I need to show the keyboard by just moving the layout of ('EditText and Send button) "up" without pushing up the other components including the bottom tab frame layout. Similarly when hiding the keyboard, the 'EditText and Send btn' layout should sit just above the tab frame layout. Can someone please suggest me the solution for this?
(Assume the situation same as in Facebook comment. When we go inside a post to comment something, the layout ('Write Comment' ET and POST btn) will be pushed up without moving any other components including the bottom tabs ('News Feed', 'Requests', 'Messenger', 'Notifications', 'More'))
I don't want to make the frame layout Visibility.Gone/Visible as it ends up in an ugly animation when the keyboard slides up/down.
Use a LinearLayout whit no weightSum, and give your main View in your layout 0dp height, and weight 1
I have the exact same issue. The best workaround I could find (as alluded to in the original question) is below. But this is a marginal solution, and not a great one.
The problem with setting the weightSum is that if the scrollview containing the edit boxes is longer, the button will disappear. The best solution would allow the buttons to stay at bottom of page on normal view, but to be hidden during keyboard onscreen.
public boolean dispatchTouchEvent(MotionEvent event) {
View v = getCurrentFocus();
boolean ret = super.dispatchTouchEvent(event);
if (v instanceof EditText) {
View w = getCurrentFocus();
int scrcoords[] = new int[2];
w.getLocationOnScreen(scrcoords);
float x = event.getRawX() + w.getLeft() - scrcoords[0];
float y = event.getRawY() + w.getTop() - scrcoords[1];
if (event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom()) ) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
layButton.setVisibility(View.VISIBLE);
}
else
{
layButton.setVisibility(View.GONE);
}
}
return ret;
}

How to avoid dispatchTouchEvent being called when click button

In my Activity, I have an EditText and a Button. I overrided the dispatchTouchEvent to hide the soft keyboard when click the other area of the screen than the EditText.
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
View view = getCurrentFocus();
boolean ret = super.dispatchTouchEvent(event);
if (view instanceof EditText) {
View w = getCurrentFocus();
int scrcoords[] = new int[2];
w.getLocationOnScreen(scrcoords);
float x = event.getRawX() + w.getLeft() - scrcoords[0];
float y = event.getRawY() + w.getTop() - scrcoords[1];
if (event.getAction() == MotionEvent.ACTION_UP
&& (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w
.getBottom())) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getCurrentFocus()
.getWindowToken(), 0);
}
}
return ret;
}
The issue is, every time I click the Button, the dispatchTouchEvent will be called, so the soft keyboard will disappear, which is not what I want. I don't want to hide the keyboard when I click the Button. What I'm thinking is that is it possible to avoid calling the dispatchTouchEvent when I click the Button?
Any feedback will be highly appreciated.
You don't need to override the dispatchTouch event. Just set the onClickListener of you activity to the same with the Button and EditText, then call the methods to hide the softkeyboard on the "default" case of the switch case.
switch (v.getId())
{
case R.id.button:
whateverButtonDoes();
break;
case R.id.editText:
whateverEditTextDoes();
break;
default:
hideKeyboard();
break;
}
I strongly suggest you define a method to hide the keyboard for clear coding standards. Also you might use it elsewhere.

Frame layout getting stuck when I hide soft input (Android)

I have an Android app (fullscreen, landscape), and I have two Views, one is a FrameLayout that's always visible, and one's a LinearLayout. I set the visibility on the LinearLayout to View.GONE right off the bat. When the user taps a button on the FrameLayout, I set visibility on the LinearLayout to view.VISIBLE, and use the InputMethodManager to show the soft input on an EditText in the LinearLayout. This results in both views being shifted up such that the EditText is on screen just above the keyboard. This is all fine.
The problem arises when I close the soft input. In the same callback, I set the visibility of the LinearLayout (with the EditText) to View.GONE, and what I'm seeing is the FrameLayout getting stuck on top of the screen (it doesn't shift back down). If I don't GONE-ize the LinearLayout, both Views shift back down just fine.
I can work around the issue by starting a timer to wait before setting the visibility to GONE, but I shouldn't have to do that; there should be some notification that I can receive consistently that will indicate when I can hide the LinearLayout.
Things I've tried: hideSoftInputFromWindow with a ResultReceiver (result receiver callback gets invoked pretty well immediately (i.e. before the keyboard actually disappears), view is GONEd too quickly, same problem), overriding onLayout for the LinearLayout (doesn't get invoked when the soft input moves the View up and down), overriding other View "on"s.
The other really annoying thing is this problem seems to be exclusive to my phone - an AT&T Samsung Galaxy SII Skyrocket running Android 4.0.4 (possibly with some Samsung modifications). I can't repro on a 4.0.3 simulator, nor can anyone else repro on other devices with other Android versions.
Any ideas?
You're going to have to write your own touch event handler. Here is an example that will slide the whole frameLayout view down when the soft input is hidden. As you can see, it is important to call the super handler and wrap our code in a test for textEdit widgets. If you want to get a look at the calculations, uncomment the debugging logger code.
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
View v = getCurrentFocus();
boolean ret = super.dispatchTouchEvent(event);
if (v instanceof EditText) {
View w = getCurrentFocus();
int scrcoords[] = new int[2];
w.getLocationOnScreen(scrcoords);
float x = event.getRawX() + w.getLeft() - scrcoords[0];
float y = event.getRawY() + w.getTop() - scrcoords[1];
// Log.d("Activity",
// "Touch event "+event.getRawX()+","+event.getRawY()+" "+x+","+y+" rect "+w.getLeft()+","+w.getTop()+","+w.getRight()+","+w.getBottom()+" coords "+scrcoords[0]+","+scrcoords[1]);
if (event.getAction() == MotionEvent.ACTION_UP
&& (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w
.getBottom())) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getCurrentFocus()
.getWindowToken(), 0);
}
}
return ret;
}

Categories

Resources