2013-01-09 123 views
3

当用户关闭一个活动并返回到上一个时,我遇到列表刷新问题。我发现这个问题非常普遍,但我无法解决。Android:从第二个活动返回时在第一个活动中刷新ListView

我重写的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); 
    } 
} 
+0

保持如果'ListView'已经包含字符串控制的一个成员变量。如果是这样,不要调用'populateList()'。 – Wroclai

+1

问题是与'列表',你如何填充这个? – Sam

+0

@Shelly - 但我需要调用populateList(),即使ListView包含字符串。我正在尝试刷新它。我不确定我是否了解你。 – Cristiano

回答

4

以及马上蝙蝠,你可以很容易地执行命令的简单条件语句敲这个客场仅在适配器是不是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();    
    } 
} 
+0

我这样说,现在它再次工作,但重复的项目仍然存在问题。例如,我有5个项目,在第二项活动中改变一项,并在返回时再次列出名单上的旧五项,1项新项目(第二项活动中改变一项)和4项旧项目再次重复。像这样,如果最后一个被编辑:a,b,c,d,e,a,b,c,d,z – Cristiano

+0

您没有为我们提供足够的代码来帮助您。但你需要检查是否有任何代码块正在初始化'list'集合没有被再次调用,可能是'onResume'事实上,你甚至需要我提出的建议让我担心事情并不是他们可能做到的。 – mango

+0

我在修改之前放了一段代码。 – Cristiano

0

你只显示应用代码的一部分,所以我在这里可以offbase,但我猜你用的是光标返回list变量并使用list来创建一个ArrayAdapter ...

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

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

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

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嵌套在您的活动,您将需要几个变量移动到GetAsyncTask用这个。但是,这种方法是更好,因为它不会强制活动以等待的结果(这可能会导致一个“应用程序没有响应”的错误。)

+0

我在修改之前放了一段代码。 – Cristiano

+0

我更新了我的答案。 – Sam

+0

感谢您对AsyncTask的建议!我给你一个:) – Cristiano

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>(); 
    } 
相关问题