Reputation: 1061
I have created a login form, where I have to edit text and buttons, which is placed in a scroll view. I want to dismiss the keyboard when I touch outside the edit text. I have implemented a scrollview onTouch Listener to dismiss keyboard, but what I want is both scroll and dismissal of the keyboard. Is it possible? Below is the code:
ScrollView sv=(ScrollView) findViewById(R.id.scroll);
sv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
InputMethodManager imm = (InputMethodManager) getSystemService( INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
});
Upvotes: 3
Views: 5423
Reputation: 51
In my case, I was able to hide keyboard when it's scrolling and it's clicking outside from edit text. Maybe this code can help. Kotlin:
nestedScrollView.setOnTouchListener(object : View.OnTouchListener{
val inputManager =
activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
if (inputManager.isAcceptingText)
inputManager.hideSoftInputFromWindow(view.windowToken, 0)
return false
}
})
Upvotes: 0
Reputation: 411
For API23+
scrollView.setOnScrollChangeListener { v, _, _, _, _ ->
v?.hideSoftKeyboard()
}
fun View.hideSoftKeyboard() {
(context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).apply {
hideSoftInputFromWindow([email protected], 0)
}
}
Upvotes: 0
Reputation: 131
Hi I tried this issue and this works for my case
scrollView.setOnTouchListener(new View.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event){if (event != null && event.getAction() == MotionEvent.ACTION_MOVE)
{
InputMethodManager imm = ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE));
boolean isKeyboardUp = imm.isAcceptingText();
if (isKeyboardUp)
{
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
return false;}
});
Upvotes: 0
Reputation: 17895
I had this same issue and fixed it with the following changes. They trick was to allow the parent scroll view to grab focus whenever no other child view wants it. For this to work, the scrollview must be clickable and focusable. This is better than using onTouchEvent
or onInterceptTouchEvent
because the ScrollView needs to leverage those for fairly complex scrolling bahavior.
First, in your layout file add these attributes to the scrollview:
android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"
Next, in your code add these listeners to your scrollview:
scrollableContent.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
onClickAway();
}
}
});
//this second listener is probably unnecessary but I put it in just in case there are weird edge cases where the scrollView is clicked but failed to gain focus
scrollableContent.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onClickAway();
}
});
Finally, implement whatever behavior you desire when the user clicks away from the fields in your form:
/**
* Invoked when something is clicked that is not otherwise listening for click events, like when
* the user clicks outside of an EditText view.
*/
protected void onClickAway() {
//hide soft keyboard
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
With these changes in place, the scrollview will gain focus anytime it is clicked and, in response, it will hide the keyboard. Note that if any other fields that require the keyboard are clicked, they will take precedence and keyboard will remain unchanged (i.e. open). Also, you could add the XML attributes and listeners to the scrollView's child ViewGroup, instead, and although I haven't tested it, I'm sure that would work, just as well.
Upvotes: 3
Reputation: 12642
you are consuming the touch event of ScrollView
by returning
return true;
just return false
It will give the touch event to the parent.
Upvotes: 4