I have created a chat activity and like facebook messenger, there is an EditText at the bottom and above is the RecyclerView of messages. When Keyboard opens, I want to scroll RecyclerView up exactly how much it should scroll up. To be more specific, lets assume there are 5 messages in the RecyclerView and currently 3rd message is just above the EditText. So when keyboard is open, I want to keep 3rd message just above the EditText like before. I have searched but could not find. If this is a duplicate question, I will be grateful if anyone can provide the link.
-
2I tried it already, did not work. – Ariful Hoque Maruf Nov 24 '17 at 12:24
-
android:windowSoftInputMode="adjustPan" try this one. – mehul chauhan Nov 24 '17 at 12:25
-
Possible duplicate of https://stackoverflow.com/questions/34102741/recyclerview-not-scrolling-to-end-when-keyboard-opens – Hemant Parmar Nov 24 '17 at 12:27
-
Well I dont want to scroll to last item @HemantParmar – Ariful Hoque Maruf Nov 24 '17 at 12:29
-
That did not work either @mehul – Ariful Hoque Maruf Nov 24 '17 at 12:34
8 Answers
recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if ( bottom < oldBottom) {
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
recyclerView.scrollToPosition(adapter.getItemCount());
}
}, 100);
}
}
});
if it not work Use smoothScrollToPosition instead of scrollToPosition
This is work for me.

- 93
- 5
Late answer but maybe someone will find it useful.
If it is a chat app then I suppose you want to start building the list from the bottom. For example, there is an empty chat and after you add a couple of message you expect them to be at the bottom of the list. Later, as there will be more and more messages, older messages will go up and newer ones will be on the bottom, right above the EditText
.
Assuming newest messages are first in your list/array you can just set the LinearLayoutManager
to be reverse layout.
layoutManager.reverseLayout = true
I can't explain why but it looks like RecyclerView
always tries to retain scroll position of the top border. So when keyboard is shown available vertical space shrinks and RecyclerView
will just try to keep its top the same as it was before. By making it reverse layout you can achieve the desired behaviour.

- 6,142
- 6
- 39
- 67
I had the same problem and I don't want to set windowSoftInputMode to "adjustResize". The above anwsers do not work for me.
editText.clearFocused();
hideKeyboard();
// update your adapter ...
parent.requestLayout();
Reset the focus of the parent layout and the recylerView will be updated correctlly.

- 1
- 2
I have been searching for the correct solution, and I found it I think.
When you place your recyclerview inside a ConstraintLayout thinking that way you can easily place your recyclerview correctly in relation to your other views (in your case your edittext), it will not work.
This used to be my layout xml, where it didnt work (I have reverseLayout=true on my LinearLayoutManager):
<androidx.constraintlayout.widget.ConstraintLayout>
<RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/editText"
app:layout_constraintTop_toBottomOf="parent" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
With this layout, everytime I opened or closed the keyboard by pressing the EditText the scroll position would move slightly up.
I fixed it by not using ConstraintLayout, but replacing it for a good old RelativeLayout like so:
<RelativeLayout>
<RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_above="@id/editText"
android:layout_height="match_parent" <!-- This is important, with 0dp it still doesnt work -->
/>
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</RelativeLayout>
When setting the RecyclerView height to match_parent it will work. (The reason we use RelativeLayout is that on ConstraintLayout, you can't set the layouth_height to match_parent of child views, it will not function properly if you do that.)

- 598
- 1
- 3
- 17
-
I had a recyclerView inside a RelativeLayout, with 0dp height, position between 2 views. Weirdly, setting the height to matchParent did the trick. (i also have 'adjustPan' set) – DoruChidean Jan 26 '21 at 11:46
I saw the best answer above recommending using reverseLayout, but that implied to invert the order of your items in the list.
You can do the same without touching your list using
layoutManager.stackFromEnd = true
instead.

- 434
- 4
- 12
Try this
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.scrollToPosition(yourPosition);

- 754
- 7
- 18
I had the same problem, what I did is when the keyboard opens, I scroll the recyclerView to the last item in the recyclerView, so no items will be hidden. I think this is much easier than the way you were proposing. So the code will be as follows:
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1);
}
}, 300);

- 14,244
- 6
- 45
- 41
-
I have done it already. I know it's easy but I dont want it. I need to scroll up exactly how it should scroll up. – Ariful Hoque Maruf Nov 24 '17 at 12:25
Write this in your Manifest
<activity
android:name=".yourActivity"
android:windowSoftInputMode="adjustResize" >
</activity>

- 754
- 7
- 18