Reputation: 3360
I want to build a message layout like WhatsApp. I have an EditText
and a RecyclerView
.
The problem is when the keyboard appears, it hide the messages at the bottom of the list.
So let's say this the RecyclerView
:
---item 1---
---item 2---
---item 3---
---item 4---
---EditText---
when the the keyboard appears, I get this:
---item 1---
---item 2---
---EditText---
---Keyboard---
but I want to get this:
---item 3---
---item 4---
---EditText---
---Keyboard---
NOTE: when I set linearLayoutManager.setStackFromEnd(true);
it works but when there is one message it appears at the bottom of the page.
Upvotes: 25
Views: 13555
Reputation: 28837
Thanks to devdoot Ghosh in Kotlin (I check if adapter size > 0):
recycler_view.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
// Wait till recycler_view will update itself and then scroll to the end.
recycler_view.post {
adapter?.itemCount?.takeIf { it > 0 }?.let {
scrollToPosition(it - 1)
}
}
}
In AndroidManifest
add to the activity:
<activity
...
android:windowSoftInputMode="adjustResize"
/>
Note that the RecyclerView
will scroll to the last item.
Upvotes: 1
Reputation: 31
I am not good at English. Use ChatRecyclerView and set the stackfromend of the linearlayoutmanager to false.
public class ChatRecyclerView extends RecyclerView {
private int oldHeight;
public ChatRecyclerView(Context context) {
super(context);
}
public ChatRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChatRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
int delta = b - t - this.oldHeight;
this.oldHeight = b - t;
if (delta < 0) {
this.scrollBy(0, -delta);
}
}
}
Upvotes: 2
Reputation: 355
I got the solution from Push up content when clicking in edit text
Just put below code in
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Upvotes: 1
Reputation: 391
set adjustresize for the activity with recyclerview and editText :
android:windowSoftInputMode="adjustResize"
add onLayoutChangeListener to your RecyclerView and set scrollToPosition to data.size() -1 in onLayoutChange:
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)
{
mRecyclerView.scrollToPosition(mMessages.size()-1);
}
});
Upvotes: 29
Reputation: 2089
The way I did it, is to set setStackFromEnd() according the size of the item holder, and set adjustResize in androidManifest.
This is how I check:
if (recycleView.getChildCount() == items.size()){
mLayoutManager.setStackFromEnd(true);
}
else{
mLayoutManager.setStackFromEnd(false);
}
Upvotes: 2