Android:从第二个活动返回时,在第一个活动中刷新ListView

时间:2013-01-09 21:10:10

标签: android android-listview refresh android-activity onresume

当用户关闭一个活动并返回上一个活动时,我遇到列表刷新问题。我发现这个问题很常见,但我无法解决。

我重写了onResume方法:

@Override
public void onResume() {
    super.onResume();
    populateList();
}

populateList()是一个方法,我用字符串列表填充listView:

arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item,list);
listView.setAdapter(arrayAdapter);

问题是,当第二个活动关闭时,新项目会再次添加到ListView中,因此我将每个项目加倍。喜欢它没有刷新。

如果我在onResume()中放入notifyDataSetChanged(),它会抛出nullPointerException,因为当第一次启动活动时,第一次启动活动时没有初始化适配器。

我不知道如何处理这个问题。

public class testActivity extends Activity {


    private int id=1;
    private ListView listView;
    private CustomArrayAdapter arrayAdapter;
    private ArrayList<String> list = new ArrayList<String>();
    ArrayList<Item> objectList = new ArrayList<Item>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

    }

    @Override
    public void onResume() {
        super.onResume();
        populateList();
    }

    private void populateList() {
        try {
            objectList = new GetAsyncTask(id).execute();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TimeoutException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        int size = objectList.size();
        String name;

        for (int i = 0; i < size; i++) {
            name = objectList.get(i).getName();
            list.add(name);
        }

        arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item,
                list);
        listView.setAdapter(arrayAdapter);
    }
}

4 个答案:

答案 0 :(得分:5)

好了,你可以轻松地用一个简单的条件语句敲掉它,只有当适配器不是null时执行命令:

    if (adapter != null) {
        adapter.notifyDataSetChanged();
    }

但在我看来,在更深层次上,您的代码可能会在某种程度上重新考虑以提高效率,但不一定更具功能性。


这样做:

private int id = 1;
private ListView listView;
private CustomArrayAdapter arrayAdapter;
private ArrayList<String> list = new ArrayList<String>();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
}

@Override
public void onResume() {
    super.onResume();
    populateList();
}

private void populateList() {

    ArrayList<Item> objectList;
    try {
        objectList = new GetAsyncTask(id).execute();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (TimeoutException e) {
        e.printStackTrace();
    }

    list.clear();
    for (int i = 0; i <objectList.size(); i++) {
        String name = objectList.get(i).getName();
        list.add(name);
    }
    if (arrayAdapter == null) {
        arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item, list);
        listView.setAdapter(arrayAdapter);
    } else {
        arrayAdapter.notifyDataSetChanged();            
    }
}

答案 1 :(得分:2)

  

我从设备中捕获list_of_files并将其放在populateList()的列表中。然后我申请适配器。返回时,设备上的列表已更改,因此它再次执行相同操作并将其放入列表中。问题出在ListView中,仍有旧项目,最后只添加了新项目。所以它是重复的。

一种基本方法是在添加新数据之前调用list.clear()。这应该删除旧数据并防止重复。 (但是如果没有看到有问题的代码,很难提供确切的答案......)


<强>加成
您应该将此代码添加到onPostExecute()内的GetAsyncTask方法:

int size = objectList.size();
String name;

list.clear(); // or list = new ArrayList<String>();
for (int i = 0; i < size; i++) {
    name = objectList.get(i).getName();
    list.add(name);
}

arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item, list);
listView.setAdapter(arrayAdapter);

除非GetAsyncTask嵌套在您的Activity中,否则您需要将一些变量移动到GetAsyncTask使用它。但这种方法更好,因为它不会强制活动等待结果(这可能会导致“应用程序无响应”错误。)

答案 2 :(得分:0)

您只显示应用程序代码的一部分,因此我可能会在此处使用,但我猜您正在使用Cursor返回list变量并使用list创建ArrayAdapter ...

如果您希望数据“新鲜”,为什么不将CursorLoader与LoaderManager一起使用? LoaderManager有几个好处(比如从UI线程移开查询),并且在监视数据库的变化时,LoaderManager会为您做一些繁重的工作。

我发现有一篇博文非常有帮助 - http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html

这是假设您从数据库中提取数据...

答案 3 :(得分:0)

问题是您正在调用函数populateList()而不先清除列表。这样填充列表只是添加到以前的内容。

这是一种正确的方式:

public void onResume() {
super.onResume();
list = new ArrayList<String>();
populateList();  }

我也不确定为什么要在函数populateList()

中设置适配器

你应该试试这个。

    private ArrayList<String> list = new ArrayList<String>();

    private ArrayList<String> populateList() {
            try {
                objectList = new GetAsyncTask(id).execute();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (TimeoutException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            int size = objectList.size();
            String name;

            for (int i = 0; i < size; i++) {
                name = objectList.get(i).getName();
                list.add(name);
            }
 return list;
        }
     arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item,
                    populateList());
            listView.setAdapter(arrayAdapter);

通过使用适配器,你可以在onResume()函数

中简单地使用它
public void onResume() {
    super.onResume();
    list = new ArrayList<String>();
    }