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.
Related
I have two fragments in one Activity and both of the fragments contain one EditText. When the the first EditText is focused (keyboard shown) and the user presses the next button of the keyboard, I am transferring the focus to the EditText in the second fragment by using this code:
View next = autoCompleteTextView.focusSearch(View.FOCUS_DOWN);
if (next != null) {
next.requestFocus();
}
The second EditText receives the focus as it should (the cursor starts blinking in it) but the keyboard that was shown, gets hidden.
I don't understand why this happens. I tried million different solutions, to force the keyboard to be shown again but nothing works. I don't know why it gets hidden in the first place, I am just transferring focus.
The only thing that worked for me is this:
mComposeMsgBody.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus && mComposeMsgBody.isEnabled()) {
mComposeMsgBody.post(new Runnable() {
#Override
public void run() {
final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mComposeMsgBody, InputMethodManager.SHOW_IMPLICIT);
}
});
}
}
});
But it is not ideal, since the keyboard tries to get hidden, and then I am forcing it go up, so there is this 1 second down-up movement that the keyboard does. If someone has a better solution for just transferring focus without the keyboard doing anything, please post an answer.
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);
}
I am trying to get the keyboard to come up when an editText view gets or has focus. I am getting the error getOnFocusChangeListener in view cannot be applied to anonymous android.view.View.OnFocusChangeListener
The error starts on new View.OnFocusChangeListener() and goes through the whole class. I can't figure out why or how to get this working.
Here is my code:
final EditText measurement = (EditText)dialog.findViewById(R.id.measurement);
measurement.getOnFocusChangeListener(new View.OnFocusChangeListener(){
#Override
public void onFocusChange(View v, boolean hasFocus){
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if(hasFocus){
imm.showSoftInput(measurement, InputMethodManager.SHOW_IMPLICIT);
}else{
imm.showSoftInput(measurement, InputMethodManager.HIDE);
}
}
});
Please help me fill in the gaps in my knowledge about why this isn't working
instead of
measurement.getOnFocusChangeListener
// you have to use
measurement.setOnFocusChangeListener
also you dont need to set a listener for edit text. whenever a edit text is clicked the softkeyboard will show up by itself, unless you are modifying certain behavior.
The question is self explanatory.
Show soft keyboard when your edit text gains focus and hide keyboard when it loses focus. Here is the code that I have used.
this.newTaskTitle = (EditText) taskCreationView.findViewById(R.id.newTaskTitle);
this.newTaskTitle.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
//Set up input manager
InputMethodManager keyboardManager = (InputMethodManager) getSystemService(
Context.INPUT_METHOD_SERVICE
);
if(hasFocus) {
Log.i(TAG,"hasFocus");
//Display keyboard
keyboardManager.showSoftInput(
v,
InputMethodManager.SHOW_IMPLICIT
);
} else {
Log.i(TAG,"lostFocus");
//Hide keyboard
keyboardManager.hideSoftInputFromInputMethod(
v.getWindowToken(),
0
);
}
}
});
Even though the else executes when the EditText loses focus, the keyboard is never hidden. Why would that be ?
Isn't this the right way to hide the keyboard ?
I think, there is no need to set OnFocusChangeListener. Call below method from onClick of your button and after calling this method set visibility GONE of your EditText.On gaining focus soft keyboard get open automatically.
private void hideKeyBoard(Context context, EditText editText) {
InputMethodManager imm = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
I have 2 editfields in my Custom Dialog which is called from ACtivity, among them 1 is of "trxtPassword" and other of "text" type. Keyboard doesn't appear in "text" type editbox, but just comes on "textPassword" edittext, and then doesn't go only.
I tried the following, but nothing works:
InputMethodManager inputManager = (InputMethodManager)mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
//inputManager.hideSoftInputFromWindow(txt_username.getWindowToken(), 0);
//inputManager.hideSoftInputFromWindow(txt_password.getWindowToken(), 0);
If I make txt_password.setInputType(0); then others can see the password easily, so that can't be used.
What more can be doen to achieve the goal? I did to trap the onLostFocus on txt
txt_password.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus == false) {
InputMethodManager inputManager = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(LoginDialog.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
}
}
});
But unfortunately, once entered, if I click anywhere else or any checkbox, then also the focus is not lost from the txt_password field. That is only lost if I click another editText and then the onFocusChange event is fired and throws error and the application shuts down.
Any idea how to accomplish this?
Use that to keep keyboard hidden on activity start
<activity
android:name=".views.DrugstoreEditView"
android:windowSoftInputMode="stateHidden"></activity>
And there is one usefull answer: How to hide soft keyboard on android after clicking outside EditText?