Hide keyboard when Edit Text in Recycler View is scrolled off screen
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)
}
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;
}
});
yourRecycleView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
edittext.clearFocus(); //hidden keyboard
return false;
}
});