Soft keyboard appears after Dialog is closed - android

Every time I have focus on some edit field and Dialog shows up, it will pull up soft keyboard as soon as I dismiss(); Dialog. I have tried every way to remove it after click event, but whatever I do it still shows up.
public static void hideSoftInput(FragmentActivity _activity){
if(_activity.getCurrentFocus() != null){
InputMethodManager inputManager = (InputMethodManager) _activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(_activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
public static void hideSoftInput(View _v, Context _c){
if(_v.getWindowToken() != null){
InputMethodManager inputManager = (InputMethodManager) _c.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(_v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}

I can't find it now but someone else on here suggested to wrap the call to hide the keyboard in a postDelayed call.
It worked for me when many other options failed. The only thing is that it may give a funny jiggle of the screen because you will be suppressing the keyboard while it is trying to show. Without the postDelayed it seems it will try to hide the keyboard before Android tries to show it after the dialog has closed. So ultimately we have to fight a timing issue in Android.
Something like this:
view.postDelayed(new Runnable()
{
#Override
public void run()
{
hideKeyboard();
}
}, 50);

Related

Android show view and hide keyboard at same time. Weird behaviour

I have a custom view that could show a view in same space that should be soft keyboard native for android.
I need to having the keyboard opened, click in a button, hide the keyboard and shows other view in same place that keyboard be/was.
I have that implemented right now just with a hide keyboard and show custom view but has a weird behavior and min lag and overlapping.
Has someone implemented a similar stuff?
I have checked the Github project and found the bug and I have fixed that bug with the following code:
if (isRedPanelVisible()) {
showRedPanel(false);
showKeyboard(true, new KeyboardCallback() {
#Override
public void onKeyboardDone(boolean isVisible) {
}
});
}
if (KeyboardVisibilityEvent.isKeyboardVisible(TestActivity.this)) {
hideKeyboard(TestActivity.this);
new android.os.Handler().postDelayed(new Runnable() {
#Override
public void run() {
showRedPanel(true);
}
}, 100);
Note: You just have to put this in TestActivity.java under button's click event and Remove the previous code.
What I did
if your readPanel is visible then I called the showRedPanel to false and try to open the keyboard.
After that I have added a check for Keyboard's visibility event and if keyboard is visible I called hideKeyboard to make keyboard go away and call showReadPanel with true after a delay of 100 ms
Code: hideKeyboard
public void hideKeyboard(Activity activity) {
// Check if no view has focus:
try {
View view = activity.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
} catch (Exception e) {
}
}
So what happens in your code is that:
Tell system to close the keyboard -> Show red panel with a small delay -> Red panel is shown before keyboard closing -> Since keyboard mode is in adjustResize the red panel shown above keyboard -> Keyboard get closed -> Everything in place
Try to change windowSoftInputMode in manifest from adjustResize to adjustNothing.
Sadly keyboard in android doesn't work smoothly like in IOS, keyboard is handled by OS means you no control over it size, opening/closing animation and no callback! So the best way is to always show red panel and when needed Open keyboard on top of it.
se the following functions to show/hide the keyboard:
/**
* Hides the soft keyboard
*/
public void hideSoftKeyboard() {
if(getCurrentFocus()!=null) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
}
/**
* Shows the soft keyboard
*/
public void showSoftKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
view.requestFocus();
inputMethodManager.showSoftInput(view, 0);
}

Android: Soft Keyboard Open & Hide Custom Dialog w/ multiple edit texts

Ok - I've bonked my head quite a bit with this. I have a custom dialog which has multiple edittexts. I've set my layout so that it does not automatically focus on the first as both are initially filled with default values (thus the user may just press 'accept')
I want any edittext to clear itself when touched and open a keyboard for numeric input. They may change one or both fields. If they touch and do not input, the field should change back to a default value.
I have implemented this with setOnFocusChangedListeners in addition to the addTextChangedListeners.
My first problem occured with the realization that the keyboard was toggling itself open/closed when a user touched both edittexts. I resolved this by using SHOW_FORCED,HIDE_NOT_ALWAYS as parameters to toggleSoftInput. Note that this was the only set of parameters which kept the keyboard open when a second field was touched.
Unfortunately, this has created a second problem which I do not understand - on exiting the dialog, I can no longer close the keyboard (ie, it remains visible on the following view). Previously, when I did not make an effort to clear the input, keyboards closed out ok. Using SHOW_IMPLICIT (ignoring the toggle issue) also has no problem with an open keyboard being closed on exit.
So.. how the * do I get this to work?
Below are some relevant sections of code:
edQuantity.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
Log.i(TAG,"edQuantity focus changed");
if (hasFocus) {
Log.i(TAG,"edQuantity HAS FOCUS");
edQuantity.setHint("");
edQuantity.setText("");
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_NOT_ALWAYS);
}
// was the other field left empty after a change attempt?
if (String.valueOf(edPrice.getText()).length()==0) edPrice.setText("0.01");
}
});
edPrice.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
Log.i(TAG,"edPrice focus changed");
if (hasFocus) {
Log.i(TAG,"edPrice HAS FOCUS");
edPrice.setHint("");
edPrice.setText("");
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_NOT_ALWAYS);
}
// was the other field left empty after a change attempt?
if (String.valueOf(edQuantity.getText()).length()==0) edQuantity.setText("1");
}
});
protected static void dismissCustomDialog(Dialog dialog, Context context) {
if (dialog != null) {
// hide the soft keyboard
if (dialog.getCurrentFocus() != null) {
Log.i(TAG,"trying to hide a keyboard");
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(dialog.getWindow().getDecorView().getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
imm.hideSoftInputFromWindow(dialog.getWindow().getDecorView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
if(dialog.isShowing()) dialog.dismiss();
}
}
As per my comment above, used a toggle to see if a keyboard was already opened.

Why is the soft keyboard being hidden on resume?

I have code like the following to immediately show the soft keyboard when entering my app:
#Override
protected void onResume() {
super.onResume();
...
myEditText.requestFocus();
myEditText.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
}
}, 100);
...
}
However, on the Android 2.1 emulator, the keyboard appears and then immediately disappears. If I make the delay longer, like 1000, it reliably appears. On an Android 4.0 emulator, a delay of 100 reliably shows the keyboard, but shorter delays do not.
Does anyone know who might be hiding the keyboard? Is there a reliable way to prevent it? If not, is there a delay I can use to guarantee that the keyboard will show?
If I understand you correctly, I think you can remove the following code in your onResume():
myEditText.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
}
}, 100);
And simply use android:windowSoftInputMode="stateAlwaysVisible" for your Activity in the manifest.
I think what you are seeing is Android identifying the view that should get focus by default and giving it focus (which hides your keyboard). Setting your delay longer or shorter just makes it so your code runs before or after that focus is set. You could figure out what view is getting focus by default, and if you don't want it to ever have focus, set it as focusable false and focusableInTouchMode false. If it does need to have focus at some point, you could set an onFocusChanged listener, and when it gets focus the first time, post your runnable(without delay) to give the focus to the EditText and open the keyboard.
Thanks to #Daniel Smith and #Cookster.
This was happening because I did not set a windowSoftInputMode in my manifest, so it was using the default value (stateUnspecified), which hid the keyboard on startup. Apparently, that setting is applied after some delay on resume, and so my call to show the keyboard only worked if my delay was longer than the built-in delay to hide it.
To fix, I set windowSoftInputMode="stateUnchanged" and then I always either hide or show the keyboard in onResume. I also removed the delay, which was no longer necessary once the built-in hiding was not happening.
Never mind, that mitigated the problem (it lets me reduce the delay), but it didn't fix it completely. There is something very nondeterministic about this, and the keyboard is no longer appearing if I don't use the delay. However, if I reintroduce a delay of about 100ms, the keyboard seems to show up about 90% of the time, which puts me back where I started: why is this happening and what's a safe delay?
put this code in onRun() in onResume() method:
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
[Edit]
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
text.requestFocus();
text.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(text, InputMethodManager.SHOW_FORCED);
}
}, 100);
text.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(text.getWindowToken(), 0);
}
}, 200);
}

How to hide keyboard automatically after sending e-mail using emailIntent

There is a page where the user can send e-mail, sms or call its guests when needed. The problem is that when the user sends e-mail to its guest, the keyboard doesn't hide. Even-though I have a small problem solving the issue, It still seems hard to find alike post to solve it. I'll be also making screenshots and placing them in here.
As you can see, the keyboard doesn't hide after sending mail.
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_EMAIL,
new String[] { **EmailAddress** });
startActivityForResult(sendIntent, 1);
#Override
protected void onActivityResult(int arg0, int arg1, Intent arg2) {
super.onActivityResult(arg0, arg1, arg2);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager inputManager = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(**AnyViewOfScreen**.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}, 300);
}
It is easy just add the following code in your manifest for the desire activity:
android:windowSoftInputMode="stateAlwaysHidden"
android:configChanges="keyboardHidden"
Its not the to override when the keyboard shows and hides itself, but here are the two methods I use to hide and show the keyboard as needed.
public void hideKeyboard(final View aView){
aView.post(new Runnable() {
#Override
public void run(){
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
public void showKeyboard(final View aView) {
aView.post(new Runnable() {
#Override
public void run() {
InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInputFromWindow(ListingScreen.this.getCurrentFocus().getWindowToken(), InputMethodManager.SHOW_FORCED, 0);
}
});
}
When you call hide/show Keyboard, pass in your current view. The post runnable thread will wait to run until the view has finished loading, then dismiss the keyboard.
Hope this helps someone :
#Override
protected void onResume() {
super.onResume();
Log.d("OnResume", "Called");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager inputManager = (InputMethodManager) LocationDetailActivity.this
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}, 300);
}
if you do not have any focusable view in your layout, just add a dummy linear layout to your xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true">
<requestFocus />
</LinearLayout>
Call This method at the place where you want to hide your keyboard if it is opened(e.g call this when you click to sendingEmail button)
protected void showVirturalKeyboard()
{
Timer timer = new Timer();
timer.schedule(new TimerTask()
{
#Override
public void run()
{
InputMethodManager m = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
if(m != null)
{
m.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
}
}, 100);
}
After trying every solution I found on StackOverflow nothing seemed to worked. In the end I did find a way to force close the keyboard, but it is not ideal.
You can set android:windowSoftInputMode="adjustPan" in the Android Manifest for that activity.
The unfortunate side effect of this is explained here http://developer.android.com/guide/topics/manifest/activity-element.html#wsoft :
"The activity's main window is not resized to make room for the soft keyboard. Rather, the contents of the window are automatically panned so that the current focus is never obscured by the keyboard and users can always see what they are typing. This is generally less desirable than resizing, because the user may need to close the soft keyboard to get at and interact with obscured parts of the window."
I had similar problem. Gmail hides the keyboard after sending. When you return to your application it focuses on something else. If you take slower device you'll see that gmail hides keyboard after sending message.

Android TextField : set focus + soft input programmatically

In my view, I have a search EditText and I would like to trigger programmatically the behaviour of a click event on the field, i.e give focus to the text field AND display soft keyboard if necessary (if no hard keyboard available).
I tried field.requestFocus(). The field actually gets focus but soft keyboard is not displayed.
I tried field.performClick(). But that only calls the OnClickListener of the field.
Any idea ?
Good sir, try this:
edittext.setFocusableInTouchMode(true);
edittext.requestFocus();
I'm not sure, but this might be required on some phones (some of the older devices):
final InputMethodManager inputMethodManager = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_IMPLICIT);
Here is the code that worked for me.
edittext.post(new Runnable() {
public void run() {
edittext.requestFocusFromTouch();
InputMethodManager lManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
lManager.showSoftInput(edittext, 0);
}
});
That's it! Enjoy ;)
The following code worked for me, after the other two answers didn't work for me:
#Override
public void onResume() {
super.onResume();
SingletonBus.INSTANCE.getBus().register(this);
//passwordInput.requestFocus(); <-- that doesn't work
passwordInput.postDelayed(new ShowKeyboard(), 300); //250 sometimes doesn't run if returning from LockScreen
}
Where ShowKeyboard is
private class ShowKeyboard implements Runnable {
#Override
public void run() {
passwordInput.setFocusableInTouchMode(true);
// passwordInput.requestFocusFromTouch();
passwordInput.requestFocus();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
}
}
After a successful input, I also make sure I hide the keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(getView().getWindowToken(), 0);
Technically, I just added 300 ms of delay before running the soft keyboard display request. Weird, right? Also changed requestFocus() to requestFocusFromTouch().
EDIT: Don't use requestFocusFromTouch() it gives a touch event to the launcher. Stick with requestFocus().
EDIT2: In Dialogs (DialogFragment), use the following
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
instead of
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
In my case, I wanted to display the virtual keyboard with no reference to a specific textbox, so I used the first part of the accepted answer to focus :
edittext.setFocusableInTouchMode(true);
edittext.requestFocus();
Then I show the virtual keyboard :
InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
for kotlin, implement using extension function as follow
fun View.showSoftKeyboard() {
this.requestFocus()
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}
field.post(new Runnable() {
#Override
public void run() {
field.requestFocus();
field.onKeyUp(KeyEvent.KEYCODE_DPAD_CENTER, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
}
});
In my case just this solved all problems:
val inputMethodManager: InputMethodManager =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_IMPLICIT)
I have put it in RecyclerView Adapter, because I use data binding.
Also I haven't used edittext.setFocusableInTouchMode(true) because in my layout it is true by default.
And don't use this line: edittext.requestFocus(). When I removed it, it started to work :)
val mAlertDialog = mBuilder.show()
//Coloca o foo no txtDlgQuantidade e então chama o teclado
mDialogView.txtDlgQuantidade.isFocusable = true
mDialogView.txtDlgQuantidade.isFocusableInTouchMode = true
mDialogView.txtDlgQuantidade.requestFocus()
mAlertDialog.window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
mAlertDialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)

Categories

Resources