使 Recycler View 从底部开始显示行

54

我曾经在某处看到过一种方法,可以使 RecyclerView 从底部向顶部显示 ViewHolders。现在,我已经找不到它了(在查阅了半个小时的 RecyclerViewRecyclerAdapterLayoutManager 等内容后)。


但是当我只有一个ViewHolder时,我希望它出现在底部等位置。此外,我也无法向上滚动并添加更多行(例如制作无限列表并在用户向上拉动时加载更多数据)。 - JoKr
8个回答

114

您是否正在寻找LinearLayoutManager.setStackFromEnd(true)方法?

编辑

事实证明,LinearLayoutManager.setReverseLayout(true)方法也可以完成任务。无论如何,读者可能需要尝试这两种方法的单独使用以及组合使用,以获得所需的效果。


1
我很蠢。我一直在查找 RecyclerView.LayoutManager 下的内容。但是我认为正确的方法是 setReverseLayout(boolean ReverseLayout),也在 LinearLayoutManager 中。我要去检查一下。 - JoKr
本来也打算提供它,但我认为它是用于另一种东西的 :) 我在我的项目中同时使用这两个工具,从顶部使行出现,并在旧行上方添加新行。 - AndroidEx
2
好的,我有一些时间来测试它:.setStackFromEnd(true) 不起作用,但是 .setReverseLayout(true) 完美地起作用。无论如何,我会接受你的答案为正确的(你可能想在答案中添加 .setReverseLayout 以供未来的观众参考)。 - JoKr
1
设置setReverseLayout和setStackFromEnd可以将行为设置为默认值。只需使用setReverseLayout就足够了。 - Dani
LinearLayoutManager构造函数的最后一个参数是reverseLayout,当设置为true时,似乎会影响我设置的ItemDecorator。如果将此参数设置为false,则ItemDecorator会按预期布置项目。 - Etienne Lawlor
4
我简直不敢相信某些本应简单的与Android相关的事情实际上是简单的。我已经习惯了在Google上搜索“如何在Android中完成[简单任务]?”并看到最受欢迎的答案大致是这样的:“一只脚做平衡动作,同时抛接三个桃子和八个椰子,还要跳过九个圈,一边哼着‘江南Style’的节奏。” - Kacy

23

这是用Kotlin编写的解决方案。

val llm = LinearLayoutManager(this)
llm.stackFromEnd = true     // items gravity sticks to bottom
llm.reverseLayout = false   // item list sorting (new messages start from the bottom)

rv_chat_history.layoutManager = llm

或者,如果您喜欢apply方法:

recycler.apply { 
    layoutManager = LinearLayoutManager(this).apply { 
        stackFromEnd = true
        reverseLayout = false
    }
}

2
一个说反向布局为假,另一个说反向布局为真。 - paul_f
1
@paul_f 那是别人编辑的,我已经纠正了。感谢你指出。 - AbhinayMe

20

您可以通过在xml代码中添加两行来完成此任务。

app:stackFromEnd="false"
app:reverseLayout="true"

这将像所有的聊天应用一样工作。


3
似乎不起作用,是否需要进行其他更改? - behelit
5
是的,如果您从服务动态加载项目,添加任何项目后应该滚动到底部,可以通过添加以下代码实现:mRecyclerView.scrollToPosition(mAdapter.getItemCount()-1); - Mostafa Anter
@MostafaAnter,也许你错了,如果我们将这两个字段一起使用,mRecyclerView.scrollToPosition(0); 将显示最新的项目(例如聊天列表),我们仅调用此行一次(不在加载更多页面时调用它)。 - Phong Nguyen
WhatsApp不使用stackFromEnd,我认为他们也没有反转布局,因为他们仍然使用ListView。他们只是每个聊天加载最后的x条消息,并滚动到底部。当您向上滚动时,它们会加载更多以前的消息。在我自己使用RecyclerView的经验中,我发现反转布局会使渲染速度变慢很多,不要问我为什么。 - Pierre

6

如果您使用的是LinearLayoutManager,请将第三个参数(reverseLayout)设置为false

LinearLayoutManager linearLayoutManager =
            new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);

0
在我的情况下,这是通过在LinearLayoutManager上设置stackFromEnd = truereverseLayout = false并设置scrollToPosition(index_of_last_element)来实现的。
recyclerView?.apply {
 layoutManager = LinearLayoutManager(context).apply {
   stackFromEnd = true
   reverseLayout = false
 }
}

recyclerView?.scrollToPosition(equations.size - 1)

查看动画


你需要设置 reverseLayout = true - Kidus Tekeste
1
感谢@KidusTekeste的建议,我知道这个论坛上大多数答案都有reverseLayout = true。然而在我的情况下,将其设置为false就有效了。您可以在提供的动画中看到它正在工作。 - xFactor

0

关于您的查询的解决方案:


LinearLayoutManager layoutManager=
                new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.VERTICAL,true);
                layoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(layoutManager); 

在上面的代码中,recyclerView是RecyclerView的ID,layoutManager是LinearLayoutManager对象。

0
花了我数小时的时间在我的这一边修复它,基本上你需要找到更新适配器之前具有最新日期和时间的消息的位置,然后在滚动到底部后更新适配器。滚动将会像WhatsApp等应用程序一样瞬间完成。
 val latestMessagePosition = liveMessagesData.size - 1
                    messagesAdaptor.setData(liveMessagesData)
                    if (latestMessagePosition >= 0) {
                        recyclerViewMessages.scrollToPosition(latestMessagePosition)
                    }

-1

This is working for me in kotlin

recyclerView?.scrollToPosition(mArrayList.size - 1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接