1

How can I hide the soft keyboard input while I am using a ScrollView in my LinearLayout?

I have tried to implement the following in my activity class, though none of these solutions produce the intended result:

(1)

@Override
public boolean onTouchEvent(MotionEvent event) 
{
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    return true;
}

(2)

@Override
public boolean onTouchEvent(MotionEvent event) 
{
    ScrollView myScrollView = (ScrollView) findViewById(R.id.scrollview); //of course scrollview was id in layout then
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    return true;
}

(3)

The same as #2, but with LinearLayout instead of ScrollView.


None of these three solutions has worked for me.

One thing I've noticed is that when I remove the ScrollView from the layout.xml file, everything works as intended.

2
  • are you sure the event is being called? everything seems normal Commented Jan 8, 2015 at 19:46
  • @RobinDijkhof Yep. I used @Override public boolean onTouchEvent(MotionEvent event) { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); return true; } function in my previous activities and everything works fine. In my opinione there is some problem with ScrollView component (but I dont know exactly what) beacause as I have said when I put in comment ScrollView component in layout xml file (res/layout-port) everything was ok. Commented Jan 8, 2015 at 19:53

4 Answers 4

8

In my case, I am generating a dynamic form which consists too many edittext fields inside a scrollview and to hide keyboard on scrolling the form I tried too many options but finally able to fix using below code:

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;
    }
});
Sign up to request clarification or add additional context in comments.

Comments

1
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    LinearLayout layout = (LinearLayout) findViewById(R.id.linear_layout_id_root);
    setHideKeyboard(this, layout);
}

public void setHideKeyboard(final Context context, View view) {
    try {
        //Set up touch listener for non-text box views to hide keyboard.
        if (!(view instanceof EditText || view instanceof ScrollView)) {

            view.setOnTouchListener(new View.OnTouchListener() {

                public boolean onTouch(View v, MotionEvent event) {
                    InputMethodManager in = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                    in.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
                    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);

                setHideKeyboard(context, innerView);
            }
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}

Comments

1

First, extend EditText and add a snippet of code that helps dismiss the keyboard every time the EditText instances lose their focus

public class MyEditText extends AppCompatEditText {

public MyEditText(Context context) {
    super(context);
    setupEditText();
}

public MyEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    setupEditText();
}

public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setupEditText();
}

public void setupEditText() {
    // Any time edit text instances lose their focus, dismiss the keyboard!
    setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus && !(findFocus() instanceof MyEditText)) {
                hideKeyboard(v);
            } else {
                showKeyboard(v);
            }
        }
    });
}

public void hideKeyboard(View view) {
    InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

public void showKeyboard(View view) {
    InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.showSoftInput(view, 0);
}
}

Then, set android:clickable="true" and android:focusableInTouchMode="true" in the child layout of your ScrollView!

Please note that, it should be the child layout of ScrollView, not ScrollView itself.

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical">

    <MyEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    </MyEditText>

</LinearLayout>

</ScrollView>

That should work!

Comments

0

The ScrollView is probably consuming the touch event. Maybe try hooking the onFocusChangeListener of your scroll view and hiding the keyboard from there?

scrollView.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus) {
            hideKeyboard();
        }
    }
});

You may need to add some attributes to the scroll view in the xml as well.

android:focusable="true"
android:focusableInTouchMode="true"

1 Comment

I put after in onCreate method in current activity your code and added log.w in order to check if method is called. I have not seen anything in debugger so that method has never been called after I had touched screen.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.