38

ListView拡張機能を使用してBaseAdapterいます。適切に更新できません。更新すると、スクロール イベントが発生するまで、古いデータが新しいデータの上に描画されているように見えます。古い行は新しい行の上に描画されますが、スクロールを開始すると古い行は消えます。

invalidateViews()notifyDataSetChanged()、およびを呼び出してみnotifyDataSetInvalidated()ました。私のコードは次のようになります。

private void updateData()
{
   List<DataItems> newList = getNewList();

   MyAdapter adapter = new MyAdapter(getContext());
   //my adapter holds an internal list of DataItems
   adapter.setList(newList);
   mList.setAdapter(adapter);
   adapter.notifyDataSetChanged();
   mList.invalidateViews();
}
4

9 に答える 9

60

まだ問題がある人のために、私はそれをこのように解決しました:

List<Item> newItems = databaseHandler.getItems();
ListArrayAdapter.clear();
ListArrayAdapter.addAll(newItems);
ListArrayAdapter.notifyDataSetChanged();
databaseHandler.close();

最初にアダプターからデータをクリアし、次に新しいアイテムのコレクションを追加してから、これを設定notifyDataSetChanged(); しました。これは最初は明確ではなかったので、これを指摘したいと思います。ビューを呼び出さnotifyDataSetChanged()ないと更新されないことに注意してください。

于 2012-09-30T16:39:59.073 に答える
13

私の理解では、データが変更されたときにすぐに ListView を更新したい場合は、 を呼び出す必要がありnotifyDataSetChanged()ますRunOnUiThread()

private void updateData() {
    List<Data> newData = getYourNewData();
    mAdapter.setList(yourNewList);

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
                mAdapter.notifyDataSetChanged();
        }
    });
}
于 2012-02-29T01:47:56.957 に答える
12

ListViewのコンテンツを更新するために新しいアダプタを作成する必要はありません。アダプタをフィールドに保存し、次のコードでリストを更新するだけです。

mAdapter.setList(yourNewList);
mAdapter.notifyDataSetChanged();

それを明確にするために、アクティビティは次のようになります。

private YourAdapter mAdapter;

protected void onCreate(...) {

    ...

    mAdapter = new YourAdapter(this);
    setListAdapter(mAdapter);

    updateData();
}

private void updateData() {
    List<Data> newData = getYourNewData();
    mAdapter.setList(yourNewList);
    mAdapter.notifyDataSetChanged();
}
于 2011-02-04T23:40:51.623 に答える
4

同じアダプターに異なるデータを補充することは、多かれ少なかれより良い手法だと思います。このメソッドを適切な引数(私の場合は名前として表示したいデータリスト)を使用してアダプタクラスに配置します。更新されたリスト(私の場合は名前)でリストのデータを更新する場所でこれを呼び出します

public void refill(ArrayList<BeanDatabase> names) {
    list.clear();
    list.addAll(names);
    list.notifyDataSetChanged();
}

リストが更新されたときにアダプターを変更したり、アダプターを何度もオンに設定したりすると、強制終了エラーが発生して問題が発生する可能性があります。(エラー: リスト データは更新されましたが、アダプターはリスト ビューに通知しません)

于 2012-02-16T05:37:16.777 に答える
3

私もinvalidate()、invalidateViews()、notifyDataSetChanged()を試しました。それらはすべて特定のコンテキストで機能する可能性がありますが、私の場合は機能しませんでした。

私の場合、リストにいくつかの新しい行を追加する必要がありましたが、うまくいきません。新しいアダプターを作成すると、問題が解決しました。

デバッグ中に、データはあるのにレンダリングされていないことに気付きました。invalidate() または invalidateViews() がレンダリングされない場合 (想定されている)、何が起こるかわかりません。

変更されたデータを更新するために新しい Adapter オブジェクトを作成することは、悪い考えではないようです。それは間違いなく機能します。唯一の欠点は、アダプターに新しいメモリを割り当てるのに時間がかかることかもしれませんが、Android システムが十分にスマートで、効率を維持するためにそれを処理していれば問題ありません。

これを式から外すと、notifyDataSetChangedを呼び出すのとほぼ同じ流れになります。その意味では、どちらの場合でも同じアダプター関数のセットが呼び出されます。

ですから、私たちは多くを失うのではなく、多くを得るのです。

于 2011-09-08T08:04:37.213 に答える
2

私はinvalidateViews()を使用して同じことをしていますが、それは私にとってはうまくいきます。すぐに無効にしたい場合は、invalidateViewsを呼び出した後にpostInvalidateを呼び出してみてください。

于 2011-02-04T23:36:20.093 に答える