3

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

我重写了 onResume 方法:

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

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

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

问题是,当第二个活动关闭时,新项目只是在 ListView 中再次添加,所以我将每个项目加倍。就像没有刷新一样。

如果我将 notifyDataSetChanged() 放在 onResume() 中,它会抛出 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

4 回答 4

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();            
    }
}
于 2013-01-09T21:20:28.830 回答
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使用它。但是这种方法更好,因为它不会强制 Activity等待结果(这可能会导致“Application Not Responding”错误。)

于 2013-01-09T21:34:50.853 回答
0

您只显示了应用程序代码的一部分,所以我可能在这里偏离了基础,但我猜您正在使用 Cursor 来返回list变量并用于list创建 ArrayAdapter ...

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

有一篇博文我觉得很有帮助 - http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html

这一切都假设您从数据库中提取数据......

于 2013-01-09T21:29:15.337 回答
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>();
    }
于 2014-04-10T20:10:49.373 回答