调用notifyDataSetChanged后,Android ListView不会更新

时间:2012-03-10 16:49:30

标签: java android android-listview android-asynctask

我有一个活动,我这样开始:

public class MyProblemsActivity extends ListActivity 
{
    String[] PROBLEMS = new String[] {"One", "Two", "Three" };
    ArrayAdapter adapter;       

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);

        adapter = new ArrayAdapter<String>(this,R.layout.my_problems, PROBLEMS);

        setListAdapter(adapter);

        ListView lv = getListView();
        lv.setTextFilterEnabled(true);

并且完全正常。

我遇到的问题是在通过Asynch调用远程服务器调用之后,我这样做:

    @Override
    protected void onPostExecute(String result) 
    {       
            PROBLEMS = new String[] {"Hello", "Bye", "Hmmmmmm" };
            adapter.notifyDataSetChanged();
        }

但是屏幕没有更新。我在这里做错了什么?如何使用新值更新屏幕?

谢谢!

3 个答案:

答案 0 :(得分:9)

正在发生的事情是

PROBLEMS = new String[] {"Hello", "Bye", "Hmmmmmm" };

PROBLEMS正在获取对new字符串数组对象的引用...因此,旧引用保持原样(未更改)..

要更正它,请使用以下内容:

PROBLEMS.clear();
List<String> newlist = new ArrayList<String>();
newlist.add(..);
..
PROBLEMS.addAll(newlist);
adapter.notifyDataSetChanged();

这样,新的字符串将仅添加到由PROBLEMS指出的现有数组引用

注意:我已经提到通过引用字符串的arraylist而不是string []来使用它的clear(),addAll()功能,你可以根据你的用途修改它为String []。 / p>

答案 1 :(得分:1)

如果您想要一个更简单的答案,您可以将代码更改为:

@Override
protected void onPostExecute(String result) 
{       
    PROBLEMS = new String[] {"Hello", "Bye", "Hmmmmmm" };
    adapter.clear();
    adapter.addAll(PROBLEMS);
    adapter.notifyDataSetChanged();
}

这会更改ArrayAdapter的内容以在新的String []中包含字符串,然后通知ListView ArrayAdapter具有新内容。这将导致ListView更新并显示您的新字符串。

答案 2 :(得分:1)

我读到您从异步回调更新了列表。我的情况也一样。我去了在UI线程中运行它,突然它按预期工作了!(通常你会得到一个例外,如果你不这样做。这里它不会刷新列表。)对于我意见,其他答案只是解决方法。

所以,改变你的代码:

@Override
protected void onPostExecute(String result) 
{                  

  runOnUiThread(new Runnable() {

    @Override
    public void run() {
            PROBLEMS = new String[] {"Hello", "Bye", "Hmmmmmm" };
            adapter.notifyDataSetChanged();
    }
});
};