【问题标题】:ListView not getting refreshed automatically, no matter whatever i try无论我尝试什么,ListView 都不会自动刷新
【发布时间】:2014-05-29 19:24:44
【问题描述】:

我知道这个问题已经被问过很多次了,甚至我已经解决了很多次这个问题,但不知何故,我在这一点上感到非常震惊,无论如何我都无法让它工作,我试着去做。请大家看看这个

我正在使用 SignalR framework 在 Android 和 .NET 中创建一个聊天应用,我已经成功地在 Android 的模型级别实现了这一点,但是视图变得很奇怪。

- SignalR Server 在这里是C# based console App。

- SignalR Client 基于 Android。

组件:

Message_Activity:

has_Method_To_Send_Message_To_SignalR_Server()

static_Method_To_Render_The_Message_Received_From_Custom_Api_Class()

Custom_Api_Class(非活动):

method_invoked_From_SignalR_Server_To_Pass_Message_&_Then_Pass_To_Message_Rendering_Method_In_Message_Activity()

流程:

- 消息通过网络从 Message_Activity 到 Console C# SignalR server 发送。

- Server send 将此消息发送给目标客户端,方法是将remote call 调用到Custom_Api_Class 中存在的方法。

- 然后此方法将该消息传递给 Message_Activityfor display in theListView 中的static Message Rendering Method。

问题:

- 在从Custom_Api_Class 接收到Message_Activity 类以在ListView 上显示消息后,它不会显示... 直到除非 ListView 正在向上或向下滚动。

结论:

- 我知道这是ListView 没有刷新的问题,我确实尝试了以下方法来解决它,但都是徒劳的......

-在ArrayAdapter上调用notifyDataSetChanged

- 在ListView 上调用invalidateViews。

- 尝试将值添加到 ArrayList<String> 中,该值进入 ArrayAdapter

- 尝试将值直接添加到ArrayAdapter。

- android:stackFromBottom="true" android:transcriptMode="alwaysScroll"

谁能告诉我这里的核心问题是什么以及任何解决方案。如果有人可以帮助我解决这个问题,我将更加感激。

编辑:

SignalR Server 调用的 Custom_Api_Class(Non-Activity) 中的代码:

 Subscription subs = hub.subscribe("receiveMessage");
     subs.addReceivedHandler(new Action<JsonElement[]>() {

      @Override
      public void run(JsonElement[] obj) throws Exception {     

MessageActivity.receiveText(obj[0].toString().replaceAll("\"","")+" "+obj[1].toString().replaceAll("\"",""));


        }
});

Custom_Api_Class 调用的 Message_Activity 中的代码:

public static void receiveText(String msgFromUser) {

        mAdapter.add(msgFromUser);
        listView_Message.post(new Runnable() {
            @Override
            public void run() {
                // Select the last row so it will scroll into view...
                listView_Message.setSelection(mAdapter.getCount() - 1);
            }
        });
        mAdapter.notifyDataSetChanged();


    }

【问题讨论】:

  • 将添加项目的代码发布到列表视图

标签: java android listview signalr android-arrayadapter


【解决方案1】:

尝试以编程方式滚动您的 listView。像这样的:

 index = listView.getFirstVisiblePosition();
 View v = listView.getChildAt(0);
 top = v.getTop();
 adapter.notifyDataSetChanged();
 listView.setSelectionFromTop(index + numOfNewElements, top);

【讨论】:

    【解决方案2】:

    经过大量的反复试验,这是我对自己问题的回答......

    - 我想通了,我的 UI thread 正在忙,而我得到的 提示 是 Toast,当时我正在做我的 System.out.println() 它工作很好,但 Toast 没有工作。

    - 所以我创建了一个Non-UI Thread,然后将输出从其中的Handler 中发布到列表中。

    - 瞧!它像黄油一样起作用。

    代码:

    new Thread(new Runnable() {
    
            @Override
            public void run() {
    
                handler.post(new Runnable() {
    
                    @Override
                    public void run() {
    
                        mAdapter.add(msgFromUser);
                        mAdapter.notifyDataSetChanged();
                        listView_Message.invalidateViews();
                    }
                });
    
            }
        }).start();
    

    【讨论】:

      【解决方案3】:

      试试下面的代码

      new Handler().postDelayed(new Runnable() {
          @Override
          //automatically disappear after given time and start game
          public void run() {
              //call your loadingTask here
      
          }
      }, refreshInterval);
      

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        我再次给出相同的答案。有多少人没有使用 Content Providers,这真是太壮观了。

        在您的情况下,您有网络操作,将数据保存在内存中并不是解决问题的有效方法。您应该在收到数据后将数据持久化到本地 SQLite 数据库。您的列表视图应该观察该数据并显示它。幸运的是,有 ContentProviders 和 CursorAdapters 。在文档中它说您不需要ContentProvider,这在某种程度上是正确的,但您可以向光标添加通知 URI。

        您应该做的是使用 CursorLoader 从 SQLite 数据库中加载您的 Cursor,并将您的 ListView 与 CursorAdapter 一起使用。在您的 SQLite 助手上,您应该为数据设置通知 URI 并注册 ContentObserver 以强制加载该数据。每次更改基础数据后,您的适配器都会获得新的光标。你会像小狗一样快乐。

        【讨论】:

        • 为什么要让 SQLite 数据库来解决这种琐碎的问题,它就像一个临时聊天室,任何两个人都可以互相交谈……而且将数据保存在 Collection 中,然后通过listView 在技术上是完全正确的......请告诉我它在这种特定情况下不起作用的原因......
        • 技术上不正确。应用程序可以随时被操作系统关闭。你会丢失你的数据。有关更多信息,请参阅this
        • 第一个 技术上没有错误,第二个操作系统可以仅介入当应用程序部分可见或完全不可见但仍在运行时关闭应用程序......但我说的是应用程序完全可见而操作系统不能的阶段在此阶段关闭应用程序。最后......我不担心数据来自哪里,但我担心 listView 不适应变化......现在请停止谈论 ContentProvider,让我知道为什么 ListView 不适应变化。
        • 你能证明你的论点吗,我很感兴趣。
        • 你不必变得咄咄逼人。你刚才说“......当应用程序完全可见并且操作系统在这个阶段无法关闭应用程序时”我真的很想看到一些证据。
        猜你喜欢
        • 2017-10-27
        • 1970-01-01
        • 1970-01-01
        • 2017-01-12
        • 2017-11-26
        • 2012-10-22
        • 2015-04-19
        • 2020-08-11
        • 2016-12-26
        相关资源
        最近更新 更多