3

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;
    }
});
peterh
  • 11,875
  • 18
  • 85
  • 108
user578386
  • 1,061
  • 3
  • 14
  • 37

5 Answers5

4

you are consuming the touch event of ScrollView by returning

return true;

just return false

It will give the touch event to the parent.

Mohsin Naeem
  • 12,542
  • 3
  • 39
  • 53
  • the thing is i want to scroll the entire view at the same time when tapped keyboard should be dismissed..i tried the above ..same result – user578386 Dec 06 '12 at 05:43
  • `scroll the entire view at the same time` you want to scroll the list view at a particular position? or adding touch listener stop scrolling? – Mohsin Naeem Dec 06 '12 at 05:47
3

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.

gMale
  • 17,147
  • 17
  • 91
  • 116
  • I tried this and it's work. But I do it slightly different, I have a `LinearLayout` inside my `ScrollView`, so I set `android:focusable="true"`, `android:focusableInTouchMode="true"` and `android:clickable="true"` to my `LinearLayout` instead of `ScrollView`. Thanks for your answer. – chitak Feb 02 '16 at 08:52
0

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;}
 });
sophie281988
  • 131
  • 9
0

For API23+

scrollView.setOnScrollChangeListener { v, _, _, _, _ ->
    v?.hideSoftKeyboard()
}
fun View.hideSoftKeyboard() {
    (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).apply {
        hideSoftInputFromWindow(this@hideSoftKeyboard.windowToken, 0)
    }
}
gd08xxx
  • 338
  • 4
  • 11
0

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
       }
   })
LuzLaura98
  • 41
  • 6