1

我伸出的ExpandableListView創建自己的列表視圖和適配器回調的實現方式是:ExpandableListView回調不同步

@Override 
public int getGroupCount() { 
    return m_FilteredSites.getSize(); 
} 

@Override 
public Object getGroup(int i) { 
    return m_FilteredSites.get(i); 
} 

@Override 
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 
    SiteEntity site = (SiteEntity) getGroup(groupPosition); 
    //more code .... 
} 

的問題是,在調用getGroupCount和getGroupView之間的m_FilteredSites集合可以改變(由於在我的情況下使用過濾器)。 有沒有一種方法來強制執行同步或任何其他方法,以保持呼叫之間的數據一致?

回答

1

現在問題已修復。 問題是我改變了工作線程而不是UI線程的m_FilteredSites集合。 Filter類有2個回調函數: 1. performFiltering - 在工作線程上執行。 2. publishResults - 在UI線程上執行。

最初我計算過濾器,但也修改performFiltering方法m_FilteredSites。 解決的辦法是將實際將m_FilteredSites集合更改爲publishResults方法的代碼。

0

您可以同步自己的代碼來訪問它,而不是按順序的同時,e.g:

ExpandableListView elv; 

synchronized(elv) { 
    // Do whatever with elv that requires exclusive thread access 
} 
+0

我看不到如何同步我的代碼會有所幫助。我不控制流量 - 這是系統回調。例如,系統將調用getGroupCount並獲得數字3(同步塊終止)。 2.現在我在另一個同步塊中更改數據,項目數變爲0. 3.現在系統調用帶編號2的getGroupView,因爲它仍認爲項目數爲3. boom。 – galbarm 2013-02-28 09:11:41

1

你不應該改變的 setAdapter() 外的內部數據。相反,您可以構建新的適配器,然後使用該方法更改它,並且一切都會好起來的。

此視頻爲ListView,但它也可以與ExpandableListViewGoogle I/O 2010 - The world of ListView。如果你有時間,我認爲值得一看。


編輯

我很抱歉,我不記得在那裏我學到這一點。我剛剛重新觀看了上面的視頻,但無法找到那一刻。我認爲notifyDataSetChanged()是在列表中的項目數據發生變化時使用的,而不是列表本身。現在,如果我沒記錯的話,你應該這樣做:

public class SampleAdapter extends BaseExpandableListAdapter { 

    private List<List<String>> mData; 

    public void updateData(List<List<String>> data) { 
     mData = data; 
     notifyDataSetChanged(); 
    } 
} 

我的意思是你不應該改變的mData(如add()remove() ...)項目。建立新列表並將其分配到mData(如上面的代碼)會更好。

如果您有content provider,您可以使用CursorTreeAdapter,它會自動爲您管理數據集。我強烈建議使用內容提供商。

+0

你的回答聽起來很合理。但是,適配器中的notifyDataSetChanged方法是否表明,在不重新創建適配器的情況下更改適配器的內部數據是「正常」? – galbarm 2013-02-28 09:31:16

+0

@galbarm對於原始答案,我很抱歉,我編輯了它... – 2013-02-28 11:28:47