当前位置: 首页 > 知识库问答 >
问题:

聊天应用程序的光标适配器加载列表自下而上

轩辕华辉
2023-03-14

我正在开发一个聊天应用程序,我正在使用光标适配器来显示聊天列表。聊天备份在服务器上,我们加载了更多聊天功能,允许用户从服务器获取他的最后50次聊天。

此loadmore按钮位于列表的顶部。

因此,当我将这些新聊天添加到我的数据库并交换光标以重新加载listview时,listview滚动位置不会被维护,列表会转到顶部,这不是正确的行为。我想保持listview滚动位置,就像按下load more聊天按钮时在Whatsapp聊天中发生的那样。

我通过使用setSelectionFromTop方法,使用以下代码成功地保持了滚动位置:

int firstVisibleItem = listView.getFirstVisiblePosition();
View view = chatList.getChildAt(0);
int pos = (view == null ? 0 : view.getBottom());
// swap cursor to reload the list
listView.setSelectionFromTop(firstVisibleItem + addedItemsCount + 1, pos);

但当我这样做时,listview给了我一个小问题,这可能是因为listview滚动位置先转到顶部,然后再回到我选择的位置。

我希望listview只是渲染新项目单独从下往上,同时保持滚动位置,就像它发生在Whatsapp中一样,没有任何故障。

我也使用了listviews stackfrombottom方法,但这似乎不起作用。

任何关于这方面的帮助都将是很大的帮助。寻找一种详细的方法来从底部到顶部呈现列表视图,同时保持其滚动位置。

谢谢。

共有1个答案

赵飞语
2023-03-14

所以我设法修复了我的问题,原来listView总是从上到下开始放置它的元素,所以要保持光标位置,您必须使用listView的setSelectionFromTop方法显式指定所选项目的位置,如下所示:-

int firstVisibleItem = listView.getFirstVisiblePosition();
View view = chatList.getChildAt(0);
int pos = (view == null ? 0 : view.getBottom());
// swap cursor to reload the list
listView.setSelectionFromTop(firstVisibleItem + addedItemsCount + 1, pos);

但这会给你一个轻微的漏洞(因为列表将从顶部开始,然后你会再次将其向下拖动),这看起来很糟糕。因此,为了克服这种情况,我们需要阻止listview对其项目进行布局。

我偶然发现了克里斯·贝恩斯(ChrisBanes)写的一篇解释如何做到这一点的伟大文章。这里是链接

要阻止listView放置其子对象,我们需要重写其layoutChildren方法。公共类BlockingListView扩展ListView{

private boolean mBlockLayoutChildren;

public BlockingListView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public void setBlockLayoutChildren(boolean block) {
    mBlockLayoutChildren = block;
}

@Override
protected void layoutChildren() {
    if (!mBlockLayoutChildren) {
        super.layoutChildren();
    }
}

}

然后执行listView。setBlockLayoutChildren(true);

int firstVisibleItem = listView.getFirstVisiblePosition();
View view = chatList.getChildAt(0);
int pos = (view == null ? 0 : view.getBottom());
// swap cursor to reload the list or notifyDataSetChange for BaseAdapter
listView.setSelectionFromTop(firstVisibleItem + addedItemsCount + 1, pos);

listView.setBlockLayoutChildren(false)

通过这种方式,我们可以阻止listView出现故障,它为我们提供了无缝的自下而上的滚动体验,同时连续加载项目,就像我们在著名的聊天应用程序(如whsApp和slack等)中所做的那样。

 类似资料:
  • 我正在使用聊天应用程序,我需要每一秒钟刷新一次列表。我使用处理程序重复调用该方法,但是它没有更新< code>ListView。我正在调用该方法中更改的通知数据集。 Messages.java 聊天适配器.java 更新的Message.java ChatDetail.xml ChatLeft.xml chattright . XML

  • 我有一个带有按钮的视图和一个列表视图,由包含bindView()和newView()的光标适配器支持,用于自定义视图。列表的每一行都包含一个Text和一个复选框。每个视图的数据来自数据库。我正在光标适配器构造函数中传递我的数据库适配器。当复选框被选中或取消选中时,我用它来更新数据库(效果很好)。当然,我对光标运行“重新查询”并view.refreshDrawableState())。这是个好主意吗

  • 我正在使用PHP,MySql和Node.js(socket.io实时聊天)像facebook这样的聊天应用程序。问题是当20个人开始聊天时,我的服务器负载会上升到10-15。我只是在发送方插入消息,并向接收方发送消息ID,接收方从数据库检索消息信息。我有一个Centos服务器有4个物理和4个逻辑核心(共8个核心)和16GB内存。我的网站是在zencart中构建的,当我在静态页面上按f5 1分钟时,

  • 问题内容: 我想知道为数千名用户编写聊天应用程序的正确方法是什么。 我只是感到困惑,我如何才能每秒使用AJAX或更少的方法来对服务器执行ping操作,并检查MySQL中是否有新记录等,并且服务器负载可以接受。 我目前正在考虑使用jQuery,PHP和MySQL进行编码。 请指教。您的帮助将不胜感激。 问题答案: 客户端 对于需要轮询服务器的任何程序,我建议使用WebSockets。 我写了一个非常

  • 我正在使用XMPP在app引擎上编写一个聊天应用程序。我的想法是允许用户互相聊天。我可以将消息发送到google talk帐户,方法是将登录的用户删除地址的@gmail.com部分,并将其替换为@appid.appspotchat.com)。例如,如果登录的用户是bob@gmail.com,则用于发送的jid将是bob@appid.appspotchat.com)。然后,您可以将消息发送到goog

  • 现在我们已经熟悉了Socket.IO,让我们编写一个聊天应用程序,我们可以用它在不同的聊天室聊天。 我们将允许用户选择用户名并允许他们使用它们进行聊天。 首先,让我们设置我们的HTML文件来请求用户名 - <!DOCTYPE html> <html> <head> <title>Hello world</title> </head> <script src = "/s