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.
Related
I just received fabric mail that my app crashed and I test it on my mobile but it's working fine but I don't why it crashes on OS 9.
context = this;
RelativeLayout parentView = findViewById(R.id.relative_cusweb_parent);
setupParent(parentView);
Above is my onCreate method & relative_cusweb_parent is main relative layout of CustomWeb Class.
private void setupParent(View view) {
if (!(view instanceof EditText)) {
view.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
hideKeyboard();
return false;
}
});
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupParent(innerView);
}
}
}
private void hideKeyboard() {
input.clearFocus();
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
imm.hideSoftInputFromWindow(Objects.requireNonNull(getCurrentFocus()).getWindowToken(), 0); // here a is crashing
}
}
App is crashing on this line
imm.hideSoftInputFromWindow(Objects.requireNonNull(getCurrentFocus()).getWindowToken(), 0);
and below is the log
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at codeline.onlinebills.activities.CustomWeb.hideKeyboard(CustomWeb.java:222)
at codeline.onlinebills.activities.CustomWeb.access$200(CustomWeb.java:38)
at codeline.onlinebills.activities.CustomWeb$4.onTouch(CustomWeb.java:231)
at android.view.View.dispatchTouchEvent(View.java:12611)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3035)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2714)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3041)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2671)
It's crashing because it doesn't find any view in focus and getCurrentFocus() returns null.
added in API level 1
public abstract View getCurrentFocus ()
Return the view in this Window that currently has focus, or null if there are none. Note that this does not look in any containing Window.
(source)
Replace this:
imm.hideSoftInputFromWindow(Objects.requireNonNull(getCurrentFocus()).getWindowToken(), 0);
with this:
imm.hideSoftInputFromWindow(getWindow().getDecorView().getRootView().getWindowToken(), 0);
You can hide keyboard with this method :
private void hideKeyBoard()
{
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
if( imm != null )
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
Try to replace your hideKeyboard method with the code below, I am using this is my app to hide the Keyboard and it works perfectly:
private void hideKeyboard() {
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
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.
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.
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 ---
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());
}
}