2010-12-07 17 views
8

基本データが変更されたときにListActivityを更新するのが難しいBaseAdapterからnotifyDataSetChangedを呼び出すときにListViewが更新されない

カスタムリスト要素(CustomListElement)でListActivityを満たすために、カスタム(リスト)アダプタ(CustomListAdapter)派生vom BaseAdapterを使用しています。

問題の要素は、時間の経過とともに、ユーザーのやりとりによって、または基礎となるデータベースの変更によって、基礎となるデータが変更される可能性があります。上記の変更を通知するために、CustomListElementおよびCustomListAdapterオブジェクトはDataSetObserverオブジェクトを登録できます。

これは本質的には、この(残念ながら全体のコードを掲示することはやり過ぎだろう)のように行われます。したがって

public class CustomListElement extends DataSetObservable { 

    protected Object value; 

    public void setValue(Object newValue) { 
     this.value = newValue; 
     notifyChanged(); 
    } 
} 

CustomListElementがDataSetObservableから継承によってregisterDataSetObserverを提供し、それがnotifyChangedだの手段()メソッドで変更を発表しました。

そしてCustomListAdapter用:

public class CustomListAdaper extends BaseAdapter { 

    protected List<CustomListElement> elementList; 

    @Override 
    public void registerDataSetObserver(DataSetObserver observer) { 
     super.registerDataSetObserver(observer); 

     for (CustomListElement element : elementList) 
      element.registerDataSetObserver(observer); 
    } 
} 

すなわち、オブザーバーは「手渡される」。今

、これは(ListActivityのsetListAdapterから呼び出された)リストビューのsetAdapterメソッド内android.widget.AbsListView.AdapterDataSetObserverを登録する必要がListActivity内

setListAdapter(new CustomListAdapter(customElementList)); 

を呼び出します。

登録されたDataSetObserverオブジェクトに変更があったことを通知すると、AdapterDataSetObserverのonChangedメソッドとそのためにListViewのrequestLayoutが呼び出されます。これは、(私の理解に)ListViewをリフレッシュする必要があります。

ただし、ListViewは新しいデータで更新されません。

notifyDataSetChangedとnotifyChangedはrunOnUiThread環境内で実行する必要がありますが、この問題は修正されていないようです。

私はまた、同様の質問が出てきたことを認識していますが、この特定のアンドロイドクラスのセットや不満足な回答はありません。

何か不足していますか?なぜこれが壊れ、どのように修正するのかについての洞察は非常に高く評価されます。

+1

はしてください[署名やキャッチフレーズを使用しない](http://stackoverflow.com/faq#signatures)あなたの記事インチ – meagar

答えて

7

AdapterインターフェイスのregisterDataSetObserver()部分は、データセットの変更時期を知りたいと思われる外部オブジェクト用です。 ListViewは本当にこれらのメソッドに興味がありません... BaseAdapterのコンテンツが変更された場合は、BaseAdapter.notifyDataSetChanged()と呼びます。これにより、ListViewに自身を更新するよう指示します。あなたはnotifyDataSetInvalidated(むしろ新しいものなどを追加するよりも)既存のアイテムの状態を変更しているので、希望)(、実際に

public void setValue(Object newValue) { 
    this.value = newValue; 
    notifyDataSetChanged(); 
} 

:つまり

は、あなただけの次の小さな変更を加える必要がありより良い選択となる。

もちろん、このデータについて知る必要のある他のオブジェクトを実際に持たない限り、そのDataSetObserverは必要ありません。

+0

'ListView.invalidateViews()'と 'Adapter.notifyDataSetChanged()'に違いはありますか? –

1

問題は解決しました。問題は実際には異なっていました(ここで言及されていない中間的なクラスは、変更に適切に反応しませんでした)。初期コードは美しく動作します。

たくさんの努力のおかげで、

+7

あなたの質問にこの情報を編集する必要があります – meagar

関連する問題