Strange Android Soft Keyboard Issue - android

I'm writing an activity, which has lots of EditText.
Their inputType are numericDecimal. Like this: Before I click
Now, I want to hide the soft keyboard when clicking somewhere other than the EditTexts, so I put:
public void hideKeyboard(View mView) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService
(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
After I click somewhere else, the numericDecimal soft keyboard do disappear. HOWEVER, there is still a common soft keyboard without autocompletion left on the screen, and I have absolutely no clue where does this come from. Showing here: After I click
So how to hide them all? Common ways on Internet don't work, I tried them all.
Thanks in advance!

Try this code :
public static void setupUI(final View view, final Activity activity) {
if (view instanceof ViewGroup) {
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Utils.hideSoftKeyboard(activity, view);
return false;
}
});
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView, activity);
}
}
}
public static void hideSoftKeyboard(Activity activity, View searchET) {
try {
InputMethodManager mgr = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(searchET.getWindowToken(), 0);
} catch (Exception e) {
e.printStackTrace();
}
}
Call the setupUI function and pass the parent Layout in your activity. It will make sure that whenever you click out of your editText it will close the keyboard.
Hope this helps.

Related

How to clear focus of multiple EditText fields in a ScrollView efficiently?

I have the following code:
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public void setupDialog(View view) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
hideKeyboard(view);
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupDialog(innerView);
}
}
}
public void setupEditTextFocusChangedListeners(View view) {
if (view instanceof EditText) {
view.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus) {
((EditText) view).setSelection(((EditText) view).getText().length());
}
}
});
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupEditTextFocusChangedListeners(innerView);
}
}
}
While the keyboard hides as it should when clicking or scrolling outside of any of the EditText fields, when scrolling the EditText still retains focus even though the keyboard does dismiss.
The EditText fields are in a table format. I know I could call clearFocus() on each EditText individually in hideKeyboard, but that doesn't seem like it would be efficient. Is there a more efficient way to clear the focus of the EditText when scrolling?
As only one EditText can be focused and you have onFocused listener you can:
private Edittext focused;
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus) {
((EditText) view).setSelection(((EditText) view).getText().length());
focused = view
}
}
And then in hideKeyboard():
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
focused.clearFocus();
}
I think this is a horrible way of doing things. You're going to screw up any touch listeners of any view other than the edit text, and its computationally expensive. I'd really suggest you not do this as all- this isn't iOS, you're expected to hit the back button to get rid of the keyboard. Trying to make it work this way is more effort than its worth, and is difficult to get right.
Ignoring that- a better way would be to make your root view of the scrollview focusable (and focusable in touch mode) with the focus of BEFORE_DESCENDENTS, and focus it onClick or onScroll. Doing it that way means you don't need to set the onTouch of every view in the hierarchy, just the base. Then in your root view onFocus, hide the keyboard when you gain focus.

How to dismiss keyboard when clicking non-EditText views in child fragment

So I find this really cool piece of code for dismissing the keyboard when I click non-EditText views. And it works very well, except for Fragments and DialogFragments started using getChildFragmentManager(). Will someone please shed some light on why the exception and how I might fix it?
public static void setupUI(View view, final Activity activity) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
LayoutUtils.hideSoftKeyboard(activity);
return false;
}
});
}
// If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView, activity);
}
}
}
private static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity
.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
I keep the code in a utility class and use it throughout my app. Essentially, for the problem case, I use it on FragmentB is started by FragmentA using getChildFragmentManager(), then the code does not affect the views of FragmentB.
try this for hide keyboard,
public void hideSoftKeyboard() {
try {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
} catch (Exception e) {
e.printStackTrace();
}
}
try the below code:
#Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
If you are using fragment use FragmentActivity not Activity. I suggest use try catch.
like
try{
InputMethodManager inputMethodManager = (InputMethodManager) activity
.getSystemService(Activity.INPUT_METHOD_SERVICE);
}catch(Exception){
InputMethodManager inputMethodManager = (InputMethodManager) fragmentactivity.getSystemService(Activity.INPUT_METHOD_SERVICE);
}
I found the solution. Maybe someone else will find it useful
public static void setupUI(View view, final Activity activity) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
LayoutUtils.hideSoftKeyboard(activity,v);
return false;
}
});
}
// If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView, activity);
}
}
}
private static void hideSoftKeyboard(Activity activity, View v) {
InputMethodManager inputMethodManager = (InputMethodManager) activity
.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
See how I replace activity.getCurrentFocus() with v. And that's it. It works in all situations now.

Dismiss keyboard when EditText loses focus

I have an EditText that I want to control the keyboard. When the EditText has focus the keyboard should appear, then as soon as I click on any other view, I want the keyboard to disappear. I try the following code but it did work
mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
} else {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
}
});
Assuming your outermost layout is RelativeLayout(You can do the similar thing for others as well), you can do something like following:
private RelativeLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//....
layout = (RelativeLayout) findViewById(R.id.yourOutermostLayout);
onTapOutsideBehaviour(layout);
}
private void onTapOutsideBehaviour(View view) {
if(!(view instanceof EditText) || !(view instanceof Button)) {
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
hideSoftKeyboard(YourCurrentActivity.this);
return false;
}
});
}
}
\\Function to hide keyboard
private static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
In onTapOutsideBehaviour function here, other that your EditText and Button views, if user clicks anywhere else, it will hide the keyboard. If you have any complex custom layout, you can exclude other views on which if user clicks, it does not hide the keyboard.
It worked for me. Hope it helps you.

Hide keypad in android while touching outside Edit Text Area

I know that the code for dismiss tyhe keypad in android is
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
Can anyone suggest me a method to hide the keypad if we touch the area outside the text area other than the keypad in the screen.
Code to dismiss Softkeyboard is below:
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
You can put it in Utility Class or if you are defining it within an activity, avoid the activity parameter, or call hideSoftKeyboard(this).
You can write a method that iterates through every View in your activity, and check if it is an instanceof EditText if it is not register a setOnTouchListener to that component and everything will fall in place. In case you are wondering how to do that, it is in fact quite simple. Here is what you do, you write a recursive method like the following.
public void setupUI(View view) {
//Set up touch listener for non-text box views to hide keyboard.
if(!(view instanceof EditText)) {
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
hideSoftKeyboard();
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
Call this method after SetcontentView() with paramet as id of your view like:
RelativeLayoutPanel android:id="#+id/parent"> ... </RelativeLayout>
Then call setupUI(findViewById(R.id.parent))
Best way you can use is DONE button besides EditText make your onClickListener to do like,
done.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
}
});
This may be old but I got this working by implenting a custom class
public class DismissKeyboardListener implements OnClickListener {
Activity mAct;
public DismissKeyboardListener(Activity act) {
this.mAct = act;
}
#Override
public void onClick(View v) {
if ( v instanceof ViewGroup ) {
hideSoftKeyboard( this.mAct );
}
}
}
public void hideSoftKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager)
getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
}
the best practice here is to create a Helper class and every container Relative / Linear Layouts should implement this.
**** Take note only the main Container should implement this class (For optimization) ****
and implement it like this :
Parent.setOnClickListener( new DismissKeyboardListener(this) );
the keyword this is for Activity. so if you are on fragment you use it like getActivity();
---thumbs up if it help you... --- cheers Ralph ---

Not able to hide Soft Keyboard for EditTextPreference

I have an EditText in a custom xml layout which get loaded dynamically(setView) in an EditTextPreference. Everything works well. Now when the preference is clicked and the editPreference dialog shows up, so does the soft keyboard. I dont want the soft keyboard to show up by default!
This is what I have tried. Should have worked :(!
public class ReportBugPreference extends EditTextPreference {
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
View viewBugReport = LayoutInflater.from(ctx).inflate(R.layout.preference_report_bug,null);
builder.setView(viewBugReport);
EditText edttxtBugDesc = (EditText) viewBugReport.findViewById(R.id.bug_description_edittext);
//edttxtBugDesc.clearFocus();
InputMethodManager inputManager = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(edttxtBugDesc.getApplicationWindowToken(), 0);
}
}
Do this for your EditText to hide Soft-Keyboard
mEditText.requestFocus();
mEditText.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager keyboard = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.hideSoftInputFromWindow(ettext.
getWindowToken(), 0);
}
},200);
i think more better way to do this is below Code :
mEditText.setInputType(InputType.TYPE_NULL);
mEditText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mEditText.setInputType(InputType.TYPE_CLASS_TEXT);
return false;
}
});
generic function that may help;
public static void hideSoftKeyboard (Context context, View view) {
try {
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getApplicationWindowToken(), 0);
}
catch (Exception ex) {
Log.w(TAG, "hideSoftKeyboard->"+ex.toString());
}
}

Categories

Resources