2013-01-09 118 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>(); 
    } 
相關問題