notifyDataSetChangedの例


166

Android ApplicationnotifyDataSetChanged()方法で使用しようとしていますArrayAdapterが、うまくいきません。

私はここ答えとして見つけまし、それnotifyDataSetChanged()はメインスレッドで実行されるはずですが、その例はありませんでした。

誰かが例または少なくともリンクを送信できますか?



あなたはこれをチェックすることができますブログとこのgithubの例同様にこれを
カベサス

回答:


328

以下のためにArrayAdapternotifyDataSetChangedあなたが使用している場合のみ動作しadd()insert()remove()、およびclear()アダプタ上。

ときArrayAdapterに構築され、それがための参照を保持Listして渡されたことを。あなたが合格した場合Listの活動のメンバーだったこと、そしてその活動の一員後に、変更ArrayAdapterまだ元への参照を保持していますList。アダプタはList、アクティビティでの変更を認識していません。

選択肢は次のとおりです。

  1. 機能を使用してArrayAdapter基本的なリストを修正するために(add()insert()remove()clear()、など)
  2. ArrayAdapter新しいListデータでを再作成します。(多くのリソースとガベージコレクションを使用します。)
  3. 由来独自のクラスを作成BaseAdapterし、ListAdapterその根底にあるの変更ができますListデータ構造。
  4. notifyDataSetChanged()リストが更新されるたびに使用します。UIスレッドで呼び出すには、runOnUiThread()ofを使用しActivityます。その後、notifyDataSetChanged()動作します。

13
データに「新しい」オブジェクトを割り当てる場合にも注意してください。代わりにclear()を使用し、データを再入力/変更してから、notifyDataSetChanged()を呼び出します
moonlightcheese

しかしnotifyDataSetChanged()、このように呼ぶとどうなり((BaseAdapter) arrayAdapter).notifyDataSetChanged();ますか?
teoREtik 2012年

2
私はBaseExpandableListAdapterを使用していますが、add()関数やremove()関数がないため、マップをメンバー変数として保存しています。Mapを更新してnotifyDatasetChanged()を呼び出しましたが、何も起こりません。選択肢#4を使用すると、うまくいきます。なぜ???
emeraldhieu

カスタムGridViewにArrayAdapterを使用しています。adapter.add(dataReceived)を呼び出して、URLから取得した画像を追加しています。これは正常に機能し、データを追加しますが、なぜデータが更新されてトップになるのですか。リストを更新せずに追加されるので、アイテムを表示します。(やりたいことは、notifyDatasetChanged()を使用してAndroidのGridViewを操作することです)このcustomGridView(StaggeredGridView)で機能させるにはどうすればよいですか。
MobileEvangelist 2013年

1
独自のBaseAdapterを作成してリストに並べ替えメソッドを追加しようとしましたが、何らかの理由で機能しません。並べ替えられたarraylistを使用してアダプター全体を再作成した場合でも、アプリが遅くなるわけではありませんが、それでもなお不快です。どのように正確に大量のゴミを作成しますか?コストのかかるデータの実際の配列は、アダプターを呼び出すアクティビティの参照として保持されていると思います。つまり、アダプターのみが収集されます。
G_V 2014年

34

このrunOnUiThread()方法は次のように使用できます。を使用していない場合はListActivity、コードを調整してへの参照を取得しますArrayAdapter

final ArrayAdapter adapter = ((ArrayAdapter)getListAdapter());
runOnUiThread(new Runnable() {
    public void run() {
        adapter.notifyDataSetChanged();
    }
});

1
私のコードにあなたのコードフラグメントを追加しようとしましたが(ここで見つけることができますstackoverflow.com/questions/3667442/how-to-refresh-adapter)onCreate-methodで、まだ成功していません:(多分それを追加するのは間違った場所だったのでしょうか?!
Tima

1
あなたの質問は、メソッドを呼び出してメインUIスレッドで実行させる方法を尋ねたところです。これはその質問に答えます。あなたの特定のケース(stackoverflow.com/questions/3670500/…)では、AsyncTaskとそのonPostExecute()メソッドを検討する必要があるようです。
Brian

12

私は最近このトピックについて書きましたが、この投稿は古いものですが、BaseAdapter.notifyDataSetChanged()ステップバイステップで正しい方法で実装する方法を知りたい人に役立つと思いました。

AndroidにBaseAdapter.notifyDataSetChanged()を正しく実装する方法または新しいブログBaseAdapter.notifyDataSetChanged()に従ってください。


こんにちは私は最初のリンクの例を試しましたが、の代わりにmItem.add()1つの要素をmItem.get(position).setImage(encodedImage)編集しましたが、そのためにエラーNullPointer exeptionが発生している可能性があります。 add()、clear()、remove()などの場合のみ
Shreekant N

notifyDataSetChangedは、データセットの編集または変更で機能します。ヌルポインターは他の原因によるものです。ログを確認してください。
Arif Nadeem、2015

7

同じ問題があり、ArrayAdapter全体を継続的に新しいインスタンスに置き換えたくない。したがって、私はAdapterHelperに重い作業をどこかで行わせています。

これを、通常(呼び出し)を呼び出す場所に追加します。

new AdapterHelper().update((ArrayAdapter)adapter, new ArrayList<Object>(yourArrayList));
adapter.notifyDataSetChanged();

AdapterHelperクラス

public class AdapterHelper {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void update(ArrayAdapter arrayAdapter, ArrayList<Object> listOfObject){
        arrayAdapter.clear();
        for (Object object : listOfObject){
            arrayAdapter.add(object);
        }
    }
}

私のコードには他にもいくつかのArrayAdapterがあり、問題なく動作しました。今夜、私はSimpleCursorAdapterをArrayAdapterに変換することにしましたが、機能しません。数時間それと格闘し、それが機能しない理由を見つけようとした後、私はあなたのAdapterHelperクラスを見つけました、そしてそれは今働きます!ありがとう!
-proudgeekdad

1
これは関数で簡単に実行できます...なぜ新しいクラスをインスタンス化するのですか?
techiServices 2012

2
Javaでは関数はメソッドと呼ばれます。あなたは何を提案しますか?この非常に再利用可能なメソッドは、おそらく配列アダプターと同じクラスにありますか?またはリストビューを含むフラグメント/アクティビティ?だから、はい、それはそれが再利用できるクラスです。どうしても静的にしたい場合は、先に進んでください。
Kevin Parker

1
良いアイデア。もう1つは、ArrayAdapterCompatという名前のArrayAdapterを拡張し、addAll(..)メソッドをオーバーライドすることです。これは、API 11以降でのみ使用できるためです。そこでAPIレベルを確認し、super.addAll(..)API> 11およびsuper.add(.. )あなたのような反復との組み合わせで:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { super.addAll(items); } else { for (Object o : collection) { super.add(o); } }。ここで、新しいアダプタクラスを拡張します。
Konsumierer、2012年

パーフェクト!@Kevinさん、本当にありがとうございました。これはまさに私が必要としていたことです!
吉備

3

私はこれが遅い対応であることを知っていますが、私は同様の問題に直面していnotifyDataSetChanged()て、適切な場所で使用することによってそれを解決することができました。

だから私の状況は次のとおりでした。

アクションバーのタブ(フラグメント)のリストビューを、まったく異なるアクティビティから返されたコンテンツで更新する必要がありました。ただし、当初、リストビューには変更が反映されませんでした。しかし、別のタブをクリックしてから目的のタブに戻ると、リストビューは他のアクティビティの正しいコンテンツで更新されます。これを解決するためにnotifyDataSetChanged()、データを返す必要があるアクティビティのコードでアクションバーアダプターを使用しました。

これは、アクティビティで使用したコードスニペットです。

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) 
    {
        case R.id.action_new_forward:

            FragmentTab2.mListAdapter.notifyDataSetChanged();//this updates the adapter in my action bar tab
            Intent ina = new Intent(getApplicationContext(), MainActivity.class);
            ina.putExtra("stra", values1);
            startActivity(ina);// This is the code to start the parent activity of my action bar tab(fragment).
    }
}

このアクティビティはいくつかのデータを返しFragmentTab2、リストビューを直接更新しFragmentTab2ます。

誰かがこれが便利だと思ってください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.