1

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 コレクションが変更される可能性があることです (私の場合はフィルターが使用されているため)。呼び出し間でデータの一貫性を維持する同期またはその他の方法を強制する方法はありますか?

4

3 に答える 3

1

この問題は修正されました。問題は、UI スレッドではなくワーカー スレッドで m_FilteredSites コレクションを変更していたことです。Filter クラスには 2 つのコールバックがあります。 1. performFiltering - ワーカー スレッドで実行されます。2. publishResults - UI スレッドで実行されます。

最初はフィルターを計算していましたが、performFiltering メソッドで m_FilteredSites も変更していました。修正は、m_FilteredSites コレクションを変更する実際のコードを publishResults メソッドに移動することです。

于 2013-04-24T08:38:54.517 に答える
1

の外部で内部データを変更しないでくださいsetAdapter()。代わりに、新しいアダプターを作成してから、その方法で変更すれば、すべて問題ありません。

このビデオは 向けですListViewが、Google I/O 2010 - リストビューの世界でExpandableListViewも機能します。時間があれば、見る価値はあると思います。


編集済み

どこで学んだか思い出せなくてすみません。上のビデオをもう一度見ましたが、その瞬間を見つけることができませんでした。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新しいリストを作成して、上記のコードのように割り当てることをお勧めします。

コンテンツ プロバイダをお持ちの場合は、 を使用できCursorTreeAdapterます。データ セットは自動的に管理されます。コンテンツ プロバイダーの使用を強くお勧めします。

于 2013-02-28T09:11:56.127 に答える
0

独自のコードを同期して、同時にアクセスするのではなく、順次アクセスすることができます。次に例を示します。

ExpandableListView elv;

synchronized(elv) {
    // Do whatever with elv that requires exclusive thread access
}
于 2013-02-28T09:06:43.887 に答える