ArrayAdapter、ListView、创建和更新内容 [英] ArrayAdapter, ListView, creating and updating contents

查看:36
本文介绍了ArrayAdapter、ListView、创建和更新内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我再次发帖,试图让问题/问题更清晰:

I posting this again, trying to make the question/problem clearer:

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 中显示它.到目前为止,一切都很好.

The code so far populates the ArrayList items, creates an adapter and adds items to this, and then shows it in the ListView lv. So far, so good.

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

However, the getShoppingList() method is run several times, updating the ArrayList items. And instead of recreating the adapter every time this happens, I'd like to just update it and display the updated contents in the ListView lv.

我正在尝试的是:

更新"按钮的 OnClick 方法:

OnClick method for the "Update" button:

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.");
        }

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

However, the lines for updating the adapter (after items have been updated) does absolutely nothing. I know that items is updated, because it's also written to a file, so the problem is not there. Besides, if I replace the lines for updating the adapter with lines for recreating it, it works nicely.

更新(2012 年 9 月 16 日):

Update (sept. 16, 2012):

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

ls.getShoppingList() 方法:

The ls.getShoppingList() method:

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;
}

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

---------- Original post ------------------

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

I have a ListView lv with an ArrayAdapter for displaying rows of items.

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

lv.setAdapter(adapter);

这很好用.填充了 items 数组列表,适配器显示了 ListView 中的内容.

This works nicely. The items arraylist is populated, and the adapter shows the contents in the ListView.

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

However, then I do some stuff that updates the ArrayList items. And then I want to update the adapter and the ListView. But this code,

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

显然不这样做.那么,如何使用更新后的项目 ArrayList 更新适配器,从而更新 ListView?不重新初始化适配器,那是什么?

obviously doesn't do it. So, how do I update the adapter and hence the ListView with the updated items ArrayList? Without reinitializing the adapter, that is?

项目 ArrayList 更新如下:

The items ArrayList is updated thusly:

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() 方法,该方法应该更新适配器,如上所述.

- New items are read into the tmpitems ArrayList. - If the number of new items are >0, a local file is updated with the tmpitems. - Then the items ArrayList is updated from the local file (with the getShoppingList() method, which adds the new entries) - Then I try running the refreshList() method, which is supposed to update the adapter, as mentioened above.

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

The items ArrayList IS updated, and the local files are updated. It's just the update method on the adapter I can't get to work. When initializing the adapter, the items are shown in the ListView - when updating it, the new contents are not.

推荐答案

使用 ((ItemArrayAdapter)lv.getAdapter()).notifyDataSetChanged() 而不是 adapter.notifyDataSetChanged()

更新:问题是 notifyDataSetChanged() 仅在适配器内部的数据发生变化时才起作用,并且它会重新呈现列表.在您的情况下,您在外部更改数据,因此您必须在适配器内部更改数据.

Update: The thing is that notifyDataSetChanged() works only when the data inside the adapter has changed, and it rerenders the list. In your case you change the data externally, so you have to change the data inside the adapter.

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

You will need to replace nlist.add(...) with insert() and remove() methods of the adapter: official reference

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

Some clarification on how it works: when you initialize adapter, it just sticks the items array you've passed to it to it's own ones. It is not aware of the changes made to your items array anymore.

这篇关于ArrayAdapter、ListView、创建和更新内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆