Home » Android » android – Hide keyboard when Edit Text in Recycler View is scrolled off screen

android – Hide keyboard when Edit Text in Recycler View is scrolled off screen

Posted by: admin May 14, 2020 Leave a comment

Questions:

I have a RecyclerView that contains EditText child elements. I would like to hide the soft keyboard when the selected EditText is scrolled off screen. How can I tell when the EditText is no longer on screen? Is there some event listener that I can attach to the EditText element to tell?

How to&Answers:

Implement onTouchListener like this:

yourRecycleView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);

        return false;
    }
});

Answer:

yourRecycleView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            edittext.clearFocus(); //hidden keyboard 
            return false;
      }
});

Answer:

My solution:

editText.setOnFocusChangeListener((v, hasFocus) -> {
            Handler handler = new Handler();
            if (!hasFocus) {
                handler.postDelayed(() -> {
                    if (!editText.hasFocus()) {
                        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                        imm.toggleSoftInput(0, 0);
                    }
                }, 200);

            }
        });

Answer:

This is what worked for me : I used RecyclerView.OnScrollListener with PublishRelay for debouncing events.

class RecyclerViewActivity : Activity(){
    ...
    private val scrollableRelay = PublishRelay.create<Unit>()
    private val disposable = CompositeDisposable()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        recyclerView.addOnScrollListener(object: RecyclerView.OnScrollListener(){
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                scrollableRelay.accept(Unit)
            }
        })
        scrollableRelay
            .debounce(100, TimeUnit.MILLISECONDS)
            .subscribe({
                if (currentFocus == recyclerView) {
                    hideKeyboard()
                }
             })
            .addTo(disposable)
    }

    override fun onDestroy() {
        disposable.onDestroy()
    }
}

Once the view is scrolled from the screen the focus goes up to recyclerView.
So, we can implement this functionality using RecyclerView.OnScrollListener.
onScrolled tracks even slightest scroll of the view. That’s why we need to add debounce that we’ll not receive a lot of events.

hideKeyboard and addTo are extension functions:

fun Disposable.addTo(compositeDisposable: CompositeDisposable) {
    compositeDisposable.add(this)
}

fun Activity.hideKeyboard() =
    currentFocus?.let {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(it.windowToken, 0)
    }