39

I am using a recycler view in reverse order to display a chat History.
If there is only one message in a chat, it displays the message at the bottom (like a Telegram). But I need to display it from the top.
I am stuck in this for a day. Can anyone please give me a suggestion to display the message from the top in Recyclerview reverse order (like WhatsApp)?

Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Saravanakumar
  • 391
  • 1
  • 3
  • 5
  • Simple sort your arraylist in descending order using `Comparator`. – Piyush Sep 12 '17 at 05:02
  • 3
    also you can use `Collections.reverse(arrayList);` method to display chat history in reverse order – Shreeya Chhatrala Sep 12 '17 at 05:05
  • 1
    try this layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); recyclerView.setLayoutManager(layoutManager); – J Ramesh Sep 12 '17 at 05:12
  • I have tried the same, But whenever I open the chat history, it shows the first message and not the last one. So, I have used getLayoutManager().scrollToPosition() to bottom of the chat. But during pagination for the chat, I found some Fluctation in the screen which jumps form one message to another. – Saravanakumar Sep 12 '17 at 05:15
  • so perhaps try this `layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true);` <--- use true or false see https://developer.android.com/reference/android/support/v7/widget/LinearLayoutManager.html#attr_RecyclerView_stackFromEnd – CrandellWS Sep 25 '18 at 09:53
  • @Saravanakumar I am stuck in the same issue, that you were facing. Have you got any solution? – Shamsul Dec 30 '19 at 09:36

11 Answers11

75

You can also use this:

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
myRecyclerView.setLayoutManager(linearLayoutManager);
Kun Szabi
  • 751
  • 5
  • 2
32

I faced the same problem some days ago. Whatever I solve this by this way.

<android.support.v7.widget.RecyclerView
android:id="@+id/reyclerview_message_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:stackFromEnd="true"
app:reverseLayout="true"/>
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Tanvir Durlove
  • 768
  • 2
  • 9
  • 21
  • 17
    If users are setting the `RecyclerView` layout manager programmatically then you need to set the `stackFromEnd` and `reverseLayout` on that instead, otherwise set the layout manager directly in the `RecyclerView` via the attribute `app:layoutManager="LinearLayoutManager"` or the layout manager of your choice other than linear. – Shadow Apr 14 '18 at 00:53
16

You can use Collections.reverse(arrayList); method to display chat history in reverse order.
Try this

ArrayList<Model> list = getList();
Collections.reverse(list);
MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter (YourActivity.this, list);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
Shreeya Chhatrala
  • 1,441
  • 18
  • 33
5

I've simply changed the ViewHolder counter order in my RecyclerView adapter.

Changed this:

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) {
    viewHolder.yourTextView.setText(mEntry.get(i));
}

To that:

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) {
    viewHolder.yourTextView.setText(mEntry.get(getItemCount() - i - 1));
}
Robert Dziubek
  • 101
  • 3
  • 8
5

This is java shortest solution:

LinearLayoutManager lm = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true); // last argument (true) is flag for reverse layout
myRecyclerView.setLayoutManager(lm);
Bamz3r
  • 177
  • 2
  • 7
5

Android recyclerview reverse order or reverse layout in kotlin

val linearLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true)
linearLayoutManager.stackFromEnd = true
Aftab Alam
  • 1,969
  • 17
  • 17
2

With Kotlin:

  mList.asReversed()  // mList : List<Modelo>
1

I had the same problem but solved it from the adapter itself.

when you add (for example) JSONArray, you can reverse the loop as follows;

for (int i=pDate.length()-1; i > -1 ; i--) {
       try {
            tModelList.add(new tModel(pData.getJSONObject(i)));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
1

Yes, different ways to achieve this but one issue is that, upon adding a new item, the recycler view will not show the new item and you'll have to manually scroll down the list. This is not user friendly. To solve this, I used RecyclerView.smoothScrollToPosition

Doing it in xml (don't forget to remove the LinearLayoutManager you attached programmatically):

<android.support.v7.widget.RecyclerView
        android:id="@+id/recordItemList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:clipToPadding="false"
        android:scrollbars="none"
        app:layoutManager="LinearLayoutManager"
        app:stackFromEnd="true"
        app:reverseLayout="true"/>

Then call smoothScrollToPosition when adding a new item

int newIndex = myArraylist.size();
myArraylist.add(newItem);
notifyItemInserted(newIndex)
myRecyclerView.smoothScrollToPosition(newIndex);

Or programmatically reverse your list with:

Collections.reverse(myArraylist);

Just before setting your adapter.

And call smoothScrollToPosition. This time, the newIndex is 0

int newIndex = 0
myArraylist.add(newIndex,newItem);
notifyItemInserted(newIndex)
myRecyclerView.smoothScrollToPosition(newIndex);
Akinyemi Jamiu
  • 431
  • 3
  • 10
0

Use this for your adapter position in onBindViewHolder

final int posRevers = list.size() - (position + 1);

0

I did something similar in this way:

layoutManager = LinearLayoutManager(context).apply {stackFromEnd = true}

And records were arranged in reverse based on time

mCursor = contentResolver.query(Uri.parse("content://sms"),
                arrayOf("body", "date", "type"),
                "address like ?",
                arrayOf("%$id"),
                "date asc")
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
taha
  • 731
  • 2
  • 7
  • 18