1

我再次发布这个,试图让问题/问题更清楚:

ListView lv;
List<Item> items;
Localstorage ls;
RemoteStorage rs;
ItemArrayAdapter adapter;

...

getShoppingList();  // <--- this method populates the items ArrayList
adapter = new ItemArrayAdapter(getApplicationContext(), R.layout.item_listitem, 
                               items);  // <--- Create an ArrayAdapter and insert the 
                                        //      ArrayList...
lv.setAdapter(adapter);

到目前为止的代码填充了 ArrayList 项目,创建了一个适配器并向其中添加项目,然后在 ListView lv 中显示它。到目前为止,一切都很好。

但是,getShoppingList() 方法会运行多次,更新 ArrayList 项。而不是每次发生这种情况时都重新创建适配器,我只想更新它并在 ListView lv 中显示更新的内容。

我正在尝试的是:

“更新”按钮的 OnClick 方法:

public void onClick(View v) {
    if (((Button)v).getText().equals("Update")) {
        try {
            tmpitems = rs.getNewEntries(cdate, latestitem);
            if (tmpitems.size() > 0) {
                updateFooter(tmpitems.size() + " new items found on server!");
                ls.UpdateLocalList(tmpitems);
                getShoppingList();               
                updateLatestItem(); 
                adapter.setNotifyOnChange(true);    //
                adapter.notifyDataSetChanged();     // THIS IS WHAT ISN'T WORKING
                lv.setAdapter(adapter);             //
            } else {
                updateFooter("No new items found on server.");
            }
        } catch (NullPointerException npe) {
            Log.e(DEBUG_TAG, "NPException i onClick(): " + npe.toString());
            updateFooter("No new items found on server.");
        }

但是,用于更新适配器的行(在更新项目之后)绝对没有任何作用。我知道项目已更新,因为它也已写入文件,所以问题不存在。此外,如果我用重新创建适配器的行替换更新适配器的行,它会很好地工作。

更新(2012 年 9 月 16 日):

private void getShoppingList () {
    items = ls.getShoppingList(SHOPPINGLIST_FILE, cdate);
}

ls.getShoppingList() 方法:

public List<Item> getShoppingList (String filename, String date) {
    String next[] = {};
    List<Item> nlist = new ArrayList<Item>();

    try {
        InputStream in = ctx.openFileInput("shoppinglists.csv");
        InputStreamReader isr = new InputStreamReader(in);
        CSVReader reader = new CSVReader(isr);

        for(;;) {
            next = reader.readNext();
            if(next != null) {
                if (next[0].equals(date)) {
                    nlist.add(new Item(next[0], next[1], next[2], 
                    next[3], next[4], next[5]));
                }
            } else {
                break;
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
        Log.e(DEBUG_TAG, "IOException in List(): " + e.toString());
    }

    return nlist;
}

---------- 原帖 ------------------

我有一个带有 ArrayAdapter 的 ListView lv,用于显示项目行。

List<Item> items;
ItemArrayAdapter adapter;
adapter = new ItemArrayAdapter(getApplicationContext(), R.layout.item_listitem, 
                               items);

lv.setAdapter(adapter);

这很好用。items arraylist 被填充,适配器在 ListView 中显示内容。

但是,然后我做了一些更新 ArrayList 项目的事情。然后我想更新适配器和 ListView。但是这段代码,

adapter.setNotifyOnChange(true);
adapter.notifyDataSetChanged();

显然不这样做。那么,如何使用更新后的项 ArrayList 更新适配器和 ListView?无需重新初始化适配器,即?

编辑:

项目 ArrayList 因此更新:

if (((Button)v).getText().equals("Update")) {
    try {
        tmpitems = rs.getNewEntries(cdate, latestitem);
            if (tmpitems.size() > 0) {
                ls.UpdateLocalList(tmpitems);
                getShoppingList();
                refreshList();
           } else {
           updateFooter("No new items found on server.");
       }
    } catch (NullPointerException npe) {
        Log.e(DEBUG_TAG, "NPException i onClick(): " + npe.toString());
        updateFooter("No new items found on server.");
    }
}

refreshList() {
    adapter.setNotifyOnChange(true);
    adapter.notifyDataSetChanged();
}

- 新项目被读入 tmpitems ArrayList。- 如果新项目的数量 > 0,则使用 tmpitems 更新本地文件。- 然后从本地文件更新项目 ArrayList(使用 getShoppingList() 方法,它添加新条目) - 然后我尝试运行 refreshList() 方法,该方法应该更新适配器,如上所述。

更新了 ArrayList 项,并更新了本地文件。这只是我无法工作的适配器上的更新方法。初始化适配器时,项目显示在 ListView 中 - 更新它时,新内容不显示。

4

1 回答 1

2

使用((ItemArrayAdapter)lv.getAdapter()).notifyDataSetChanged()代替adapter.notifyDataSetChanged()

更新: 事情是notifyDataSetChanged()只有当适配器的数据发生变化时才有效,并且它会重新呈现列表。在您的情况下,您从外部更改数据,因此您必须更改适配器内部的数据。

您将需要替换适配器的nlist.add(...)insert()方法:官方参考remove()

关于它如何工作的一些说明:当您初始化适配器时,它只是将您传递给它的 items 数组粘贴到它自己的数组中。它不再知道对您的 items 数组所做的更改。

于 2012-09-14T20:58:13.887 回答