user578386
user578386

Reputation: 1061

How to dismiss keyboard from editText when placed in scroll view?

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

Answers (5)

LuzLaura98
LuzLaura98

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

gd08xxx
gd08xxx

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

sophie281988
sophie281988

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

gMale
gMale

Reputation: 17895

Description

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.

Code Changes

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);
}

Results

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

Mohsin Naeem
Mohsin Naeem

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

Related Questions