david
david

Reputation: 3360

How to push RecyclerView up when the soft keyboard appears?

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

Answers (5)

CoolMind
CoolMind

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

minjung Ahn
minjung Ahn

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

hikky36
hikky36

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

devdoot Ghosh
devdoot Ghosh

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

VHanded
VHanded

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

Related Questions