I am using recylerview in my application and whenever new element is added to recyclerview, it scrolls to last element by using
recyclerView.scrollToPosition
Bind the RecyclerView inside NestedScrollView
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v4.widget.NestedScrollView>
You can catch keyboard up changes using recyclerview.addOnLayoutChangeListener()
.
If bottom is smaller than oldBottom
then keyboard is in up state.
if ( bottom < oldBottom) {
recyclerview.postDelayed(new Runnable() {
@Override
public void run() {
recyclerview.smoothScrollToPosition(bottomPosition);
}
}, 100);
}
I found the postDelayed
to be unnecessary and using adapter positions doesn't account for when the recycler is scrolled to somewhere in the middle of an item. I achieved the look I wanted with this:
recycler.addOnLayoutChangeListener((view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
if (bottom < oldBottom) {
messageRecycler.scrollBy(0, oldBottom - bottom);
}
})
This works.
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private LinearLayoutManager mManager;
...
mManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mManager);
(initialize and set adapter.)
mRecyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (bottom < oldBottom) scrollToBottom();
}
});
private void scrollToBottom() {
mManager.smoothScrollToPosition(mRecyclerView, null, mAdapter.getItemCount());
}