Vous devez l'exécuter sur le thread d'interface utilisateur. Créez un gestionnaire dans le thread d'interface utilisateur, puis postez-y Runable
Kirill Kulakov
11
Encore une fois: notifyDataSetChanged () ne fonctionne pas du moins pour les pratiques d'utilisation recommandées (lecture non déconseillée). Si vous utilisez listview, l'adaptateur de curseur et le fournisseur de contenu, vous pouvez essayer quelque chose du genre: gettLoaderManager (). RestartLoader (). Voir: stackoverflow.com/a/19657500/1087411 Je voudrais voir au moins de la documentation sur notifyDataSetChanged (). Trop dans Android est laissé aux tests de la boîte noire.
Anderson
Si notifyDataSetChanged ne fonctionne pas, c'est vous qui le faites mal
zdarsky.peter
4
notifyDataSetChanged ne fonctionne pas toujours. Je ne sais pas pourquoi cela est en litige. Parfois, vous devez appeler listView.setAdapter (adaptateur) pour effacer les anciennes vues. Voir aussi: stackoverflow.com/a/16261588/153275
1
Je n'ai jamais réussi à faire fonctionner notifyDataSetChanged. Je pouvais clairement voir que la collection que j'alimente à l'adaptateur a changé (les éléments ont été supprimés) mais notifyDataSetChanged n'a jamais rien fait. Vous ne savez pas si cette méthode est juste cassée?
C'est la bonne réponse si l'on a seulement besoin de REDESSINER la vue. Par exemple, après la connexion d'un utilisateur, il doit afficher plus d'informations ou d'options dans chaque vue de listView. C'est ce que je devais faire, alors j'ai voté pour. Si les données sous-jacentes changent, c'est probablement une meilleure idée d'utiliser notifyDataSetChanged ().
SBerg413
En fait, invalidateViews()dans les ensembles de codes sources mDataChanged = true;, je ne sais pas si cela se traduit par de meilleures performances par rapport ànotifyDataSetChanged()
vovahost
Tu m'as sauvé la journée, mec!
oskarko
vous pouvez prendre un type de liste qui est "liste observable", pas besoin de notifydataset changé
Priya
153
S'il vous plaît ignorer tous les invalidate(), invalidateViews(), requestLayout(), ... réponses à cette question.
Si l'appel notifyDataSetChanged()ne fonctionne pas, toutes les méthodes de mise en page ne seront pas utiles non plus. Croyez-moi, le a ListViewété correctement mis à jour. Si vous ne trouvez pas la différence, vous devez vérifier d'où proviennent les données de votre adaptateur.
S'il ne s'agit que d'une collection que vous gardez en mémoire, vérifiez que vous avez réellement supprimé ou ajouté les éléments à la collection avant d'appeler le notifyDataSetChanged().
Si vous travaillez avec une base de données ou un backend de service, vous devrez appeler la méthode pour récupérer à nouveau les informations (ou manipuler les données en mémoire) avant d'appeler le notifyDataSetChanged().
Le truc, c'est que cela notifyDataSetChangedne fonctionne que si l'ensemble de données a changé. C'est donc l'endroit à rechercher si vous ne trouvez pas de changements à venir. Déboguez si nécessaire.
ArrayAdapter vs BaseAdapter
J'ai trouvé que travailler avec un adaptateur qui vous permet de gérer la collection, comme un BaseAdapter fonctionne mieux. Certains adaptateurs comme ArrayAdapter gèrent déjà leur propre collection, ce qui rend plus difficile l'accès à la bonne collection pour les mises à jour. C'est vraiment juste une couche de difficulté supplémentaire inutile dans la plupart des cas.
Fil d'interface utilisateur
Il est vrai que cela doit être appelé à partir du thread d'interface utilisateur. D'autres réponses contiennent des exemples sur la façon d'y parvenir. Cependant, cela n'est requis que si vous travaillez sur ces informations en dehors du thread d'interface utilisateur. Cela provient d'un service ou d'un thread non UI. Dans des cas simples, vous mettrez à jour vos données à partir d'un clic sur un bouton ou d'une autre activité / fragment. Donc toujours dans le thread d'interface utilisateur. Pas besoin de toujours insérer ce runOnUiTrhead.
Exemple de projet rapide
Peut être trouvé à https://github.com/hanscappelle/so-2250770.git . Il vous suffit de cloner et d'ouvrir le projet dans Android Studio (gradle). Ce projet a un bâtiment MainAcitivityListView avec toutes les données aléatoires. Cette liste peut être actualisée à l'aide du menu d'action.
L'implémentation de l'adaptateur que j'ai créée pour cet exemple ModelObject expose la collecte de données
publicclassMyListAdapterextendsBaseAdapter{/**
* this is our own collection of data, can be anything we
* want it to be as long as we get the abstract methods
* implemented using this data and work on this data
* (see getter) you should be fine
*/privateList<ModelObject> mData;/**
* our ctor for this adapter, we'll accept all the things
* we need here
*
* @param mData
*/publicMyListAdapter(finalContext context,finalList<ModelObject> mData){this.mData = mData;this.mContext = context;}publicList<ModelObject> getData(){return mData;}// implement all abstract methods here}
Code de la MainActivity
publicclassMainActivityextendsActivity{privateMyListAdapter mAdapter;@Overrideprotectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);ListView list =(ListView) findViewById(R.id.list);// create some dummy data hereList<ModelObject> objects = getRandomData();// and put it into an adapter for the list
mAdapter =newMyListAdapter(this, objects);
list.setAdapter(mAdapter);// mAdapter is available in the helper methods below and the // data will be updated based on action menu interactions// you could also keep the reference to the android ListView // object instead and use the {@link ListView#getAdapter()} // method instead. However you would have to cast that adapter // to your own instance every time}/**
* helper to show what happens when all data is new
*/privatevoid reloadAllData(){// get new modified random dataList<ModelObject> objects = getRandomData();// update data in our adapter
mAdapter.getData().clear();
mAdapter.getData().addAll(objects);// fire the event
mAdapter.notifyDataSetChanged();}/**
* helper to show how only changing properties of data
* elements also works
*/privatevoid scrambleChecked(){Random random =newRandom();// update data in our adapter, iterate all objects and // resetting the checked optionfor(ModelObject mo : mAdapter.getData()){
mo.setChecked(random.nextBoolean());}// fire the event
mAdapter.notifyDataSetChanged();}}
vous vous trompez. notifyDataSetChanged () n'a pas fonctionné pour moi, mais invalidateViews () l'a fait correctement.
babay
6
J'ai le problème où les éléments réels de la liste ne changent pas, par exemple la même quantité d'éléments. Mais le problème est que la façon dont ils sont présentés doit changer. Cela signifie que le code de mon adaptateur pour créer l'interface utilisateur doit s'exécuter à nouveau, puis masquer correctement certains éléments dans les lignes de la liste. notifyDataSetChanged () ne fonctionne pas ...
Sven Haiges
9
Cette réponse m'a vraiment aidé. Je gardais le tableau en mémoire pour certaines raisons de fonctionnalité. Pour résoudre ce problème adapter.clear(), j'appelle maintenant , et adapter.addAll(Array<T>)avant d'appelernotifyDataSetChanged()
Michael DePhillips
2
@hcpl, comment dois-je appeler notifyDataSetChanged si je suis dans OnClickListener de l'adaptateur pour un CheckBox? invalidateViews fait le travail en ce moment. Pourquoi invalidateViews n'est-il pas la bonne méthode à appeler?
grue le
1
Je n'ai jamais réussi à faire fonctionner notifyDataSetChanged. Je pouvais clairement voir que la collection que j'alimente à l'adaptateur a changé (les éléments ont été supprimés) mais notifyDataSetChanged n'a jamais rien fait. Vous ne savez pas si cette méthode est juste cassée?
Fonctionnant également dans mon cas, où j'ai besoin de mettre à jour une liste en fonction des données provenant d'une connexion TCP (à partir d'un thread "nonUI"). La seule façon de redessiner la liste était d'effacer et de rajouter tous les éléments de la ArrayList. Quoi qu'il en soit, si vous êtes déjà dans le thread d'interface utilisateur, vous n'avez pas besoin d'appeler le code via la runOnUiThread()fonction.
Andre
Merci! Ça marche pour moi. Pour toutes les personnes qui souhaitent exécuter cela à partir d'un fragment, vous devez utiliser getActivity (). RunOnUiThread (new Runnable ... pour vous assurer que le code est exécuté sur le thread d'interface utilisateur
codingpuss
Je ne vois pas le but de run = new Runnable()et ai juste donné à ma fonction une public void refreshUIThread()méthode qui modélise votre run()méthode (qui fonctionne aussi).
T.Woody
11
J'ai eu quelques problèmes avec l'actualisation dynamique de ma liste.
Appelez notifyDataSetChanged () sur votre adaptateur.
Quelques détails supplémentaires sur la façon / le moment d'appeler notifyDataSetChanged () peuvent être consultés dans cette vidéo Google I / O.
notifyDataSetChanged () ne fonctionnait pas correctement dans mon cas [j'ai appelé le notifyDataSetChanged d'une autre classe]. Juste au cas où j'ai édité le ListView dans l'activité en cours (Thread). Cette vidéo grâce à Christopher a donné l'ultime indice.
Dans ma deuxième classe, j'ai utilisé
Runnable run =newRunnable(){publicvoid run(){
contactsActivity.update();}};
contactsActivity.runOnUiThread(run);
pour accéder à la mise à jour () de mon Activité. Cette mise à jour comprend
myAdapter.notifyDataSetChanged();
pour indiquer à l'adaptateur d'actualiser la vue. A bien fonctionné pour autant que je puisse dire.
si vous n'êtes pas encore satisfait de l'actualisation de ListView, vous pouvez consulter cet extrait, c'est pour charger la listView à partir de la base de données.En réalité, ce que vous avez à faire est simplement de recharger ListView, après avoir effectué une opération CRUD, ce n'est pas le meilleur moyen de mais il actualisera le ListView comme vous le souhaitez.
Cela fonctionne pour moi .... si vous trouvez une meilleure solution, veuillez partager ...
.......
......
faites vos opérations CRUD ..
......
.....
DBAdapter.open ();
DBAdapter.insert_into_SingleList ();
// Apportez ces résultats DB et ajoutez-les à la liste en tant que contenu ....
ls2.setAdapter (new ArrayAdapter (DynTABSample.this,
android.R.layout.simple_list_item_1, DBAdapter.DB_ListView));
DBAdapter.close ();
Les solutions proposées par les personnes dans ce post fonctionnent ou non en fonction principalement de la version Android de votre appareil. Par exemple, pour utiliser la méthode AddAll, vous devez mettre android: minSdkVersion = "10" dans votre appareil Android.
Pour résoudre ces questions pour tous les appareils, j'ai créé ma propre méthode dans mon adaptateur et j'utilise à l'intérieur de la méthode d'ajout et de suppression héritée d'ArrayAdapter qui met à jour vos données sans problème.
Mon code: en utilisant ma propre classe de données RaceResult, vous utilisez votre propre modèle de données.
ResultGpRowAdapter.java
publicclassResultGpRowAdapterextendsArrayAdapter<RaceResult>{Context context;int resource;List<RaceResult> data=null;publicResultGpRowAdapter(Context context,int resource,List<RaceResult> objects){super(context, resource, objects);this.context = context;this.resource = resource;this.data = objects;}@OverridepublicView getView(int position,View convertView,ViewGroup parent){........}//my own method to populate data publicvoid myAddAll(List<RaceResult> items){for(RaceResult item:items){super.add(item);}}
ResultsGp.java
publicclassResultsGpextendsActivity{@Overrideprotectedvoid onCreate(Bundle savedInstanceState){......................ListView list =(ListView)findViewById(R.id.resultsGpList);ResultGpRowAdapter adapter =newResultGpRowAdapter(this, R.layout.activity_result_gp_row,newArrayList<RaceResult>());//Empty data
list.setAdapter(adapter);............//LOAD a ArrayList<RaceResult> with dataArrayList<RaceResult> data =newArrayList<RaceResult>();
data.add(newRaceResult(....));
data.add(newRaceResult(....));.......
adapter.myAddAll(data);//Your list will be udpdated!!!
Vous devez utiliser un seul objet de cette liste dont les données que vous gonflez ListView . Si la référence est modifiée, notifyDataSetChanged()cela ne fonctionne pas. Chaque fois que vous supprimez des éléments de la liste, supprimez-les également de la liste que vous utilisez, qu'il s'agisse d'une liste de tableaux <> ou de quelque chose d'autre, puis appelez un
notifyDataSetChanged()objet de votre classe d'adaptateur.
Alors, voici comment je l'ai géré dans mon adaptateur, voir ci-dessous
Je n'ai pas pu obtenir notifyDataSetChanged () pour travailler sur la mise à jour de mon SimpleAdapter, j'ai donc essayé de supprimer d'abord toutes les vues qui étaient attachées à la disposition parent à l'aide de removeAllViews (), puis d'ajouter ListView, et cela a fonctionné, ce qui m'a permis de mettre à jour le UI:
Pour moi, après avoir modifié les informations dans la base de données SQL, rien ne pouvait actualiser la vue de liste (pour être une vue de liste expansible spécifique), donc si notifyDataSetChanged () ne vous aide pas, vous pouvez essayer de vider votre liste en premier et de l'ajouter à nouveau après cet appel notifyDataSetChanged (). Par exemple
J'étais le même lorsque, dans un fragment, j'ai voulu remplir un ListView (dans un seul TextView) avec l'adresse mac des appareils BLE scannés pendant un certain temps.
Je pense que cela dépend de ce que vous entendez par rafraîchissement. Voulez-vous dire que l'affichage de l'interface graphique doit être actualisé, ou voulez-vous dire que les vues enfant doivent être actualisées de sorte que vous pouvez appeler par programme getChildAt (int) et obtenir la vue correspondant à ce qui se trouve dans l'adaptateur.
Si vous souhaitez que l'affichage de l'interface graphique soit actualisé, appelez notifyDataSetChanged () sur l'adaptateur. L'interface graphique sera actualisée lors du prochain redessin.
Si vous voulez pouvoir appeler getChildAt (int) et obtenir une vue qui reflète ce qui se trouve dans l'adaptateur, appelez alors layoutChildren (). Cela entraînera la reconstruction de la vue enfant à partir des données de l'adaptateur.
J'avais une ArrayList que je voulais afficher dans une liste. ArrayList contenait des éléments de mysql. J'ai remplacé la méthode onRefresh et dans cette méthode, j'ai utilisé tablelayout.removeAllViews (); puis répété le processus d'obtention à nouveau des données de la base de données. Mais avant cela, assurez-vous d'effacer votre ArrayList ou toute autre structure de données, sinon de nouvelles données seront ajoutées à l'ancienne.
Si vous souhaitez mettre à jour la liste de l'interface utilisateur à partir d'un service, rendez l'adaptateur statique dans votre activité principale et procédez comme suit:
Si vous utilisez des lignes de guidage Android et que vous utilisez ContentProviderspour obtenir des données Databaseet que vous les affichez à l' ListViewaide de CursorLoaderet CursorAdapters, alors toutes les modifications apportées aux données associées seront automatiquement reflétées dans ListView.
Votre getContext().getContentResolver().notifyChange(uri, null);curseur ContentProvidersera suffisant pour refléter les changements. Pas besoin de travail supplémentaire.
Mais lorsque vous ne les utilisez pas tous, vous devez indiquer à l'adaptateur lorsque l'ensemble de données change. Vous devez également repeupler / recharger votre jeu de données (par exemple, la liste), puis vous devez appeler notifyDataSetChanged()l'adaptateur.
notifyDataSetChanged()ne fonctionnera pas s'il n'y a pas de changements dans le jeu de données. Voici le commentaire au-dessus de la méthode dans docs-
/**
* Notifies the attached observers that the underlying data has been changed
* and any View reflecting the data set should refresh itself.
*/
Je n'ai pu obtenir notifyDataSetChanged qu'en obtenant de nouvelles données d'adaptateur, puis en réinitialisant l'adaptateur pour la vue de liste, puis en effectuant l'appel comme suit:
sur une autre option est la onWindowFocusChangedméthode, mais bien sûr, elle est sensible et a besoin d'un codage supplémentaire pour qui est intéressé
override fun onWindowFocusChanged(hasFocus:Boolean){super.onWindowFocusChanged(hasFocus)// some controls needed
programList = usersDBHelper.readProgram(model.title!!)
notesAdapter =DailyAdapter(this, programList)
notesAdapter.notifyDataSetChanged()
listview_act_daily.adapter = notesAdapter
}
Si j'ai parlé de mon scénario ici, aucune des réponses ci-dessus ne fonctionnera parce que j'ai eu une activité qui affiche la liste des valeurs de base de données avec un bouton de suppression et lorsqu'un bouton de suppression est enfoncé, je voulais supprimer cet élément de la liste.
Le truc cool, c'est que je n'ai pas utilisé la vue recycleur mais une simple vue liste et cette vue liste initialisée dans la classe adaptateur. Ainsi, l'appel à notifyDataSetChanged()ne fera rien à l'intérieur de la classe d'adaptateur et même dans la classe d'activité où l'objet adaptateur est initialisé car la méthode delete était dans la classe d'adaptateur.
Ainsi, la solution était de supprimer l'objet de l'adaptateur dans la getViewméthode de classe d'adaptateur (pour supprimer uniquement cet objet spécifique mais si vous souhaitez tout supprimer, appelez clear()).
Pour vous faire une idée, à quoi ressemblait mon code,
publicclassWordAdapterextendsArrayAdapter<Word>{Context context;publicWordAdapter(Activity context,ArrayList<Word> words){}//.......@NonNull@OverridepublicView getView(finalint position,View convertView,ViewGroupgroup){//.......ImageButton deleteBt = listItemView.findViewById(R.id.word_delete_bt);
deleteBt.setOnClickListener(newView.OnClickListener(){@Overridepublicvoid onClick(View v){if(vocabDb.deleteWord(currentWord.id)){//.....}else{//.....}remove(getItem(position));// <---- here is the trick ---<//clear() // if you want to clear everything}});//....
Remarque: ici remove()et les getItem()méthodes sont héritées de la classe Adapter.
remove() - pour supprimer l'élément spécifique qui est cliqué
getItem(position) - est d'obtenir l'élément (ici, c'est mon objet Word que j'ai ajouté à la liste) à partir de la position cliquée.
Voici comment j'ai défini l'adaptateur sur la liste dans la classe d'activité,
Réponses:
Appelez
notifyDataSetChanged()
votreAdapter
objet une fois que vous avez modifié les données de cet adaptateur.En voici quelques détails supplémentaires sur la façon / quand appeler
notifyDataSetChanged()
peuvent être consultés dans cette vidéo Google I / O .la source
Vous pouvez également utiliser ceci:
la source
invalidateViews()
dans les ensembles de codes sourcesmDataChanged = true;
, je ne sais pas si cela se traduit par de meilleures performances par rapport ànotifyDataSetChanged()
S'il vous plaît ignorer tous les
invalidate()
,invalidateViews()
,requestLayout()
, ... réponses à cette question.La bonne chose à faire (et heureusement également marquée comme bonne réponse) est de faire appel
notifyDataSetChanged()
à votre adaptateur .Dépannage
Si l'appel
notifyDataSetChanged()
ne fonctionne pas, toutes les méthodes de mise en page ne seront pas utiles non plus. Croyez-moi, le aListView
été correctement mis à jour. Si vous ne trouvez pas la différence, vous devez vérifier d'où proviennent les données de votre adaptateur.S'il ne s'agit que d'une collection que vous gardez en mémoire, vérifiez que vous avez réellement supprimé ou ajouté les éléments à la collection avant d'appeler le
notifyDataSetChanged()
.Si vous travaillez avec une base de données ou un backend de service, vous devrez appeler la méthode pour récupérer à nouveau les informations (ou manipuler les données en mémoire) avant d'appeler le
notifyDataSetChanged()
.Le truc, c'est que cela
notifyDataSetChanged
ne fonctionne que si l'ensemble de données a changé. C'est donc l'endroit à rechercher si vous ne trouvez pas de changements à venir. Déboguez si nécessaire.ArrayAdapter vs BaseAdapter
J'ai trouvé que travailler avec un adaptateur qui vous permet de gérer la collection, comme un BaseAdapter fonctionne mieux. Certains adaptateurs comme ArrayAdapter gèrent déjà leur propre collection, ce qui rend plus difficile l'accès à la bonne collection pour les mises à jour. C'est vraiment juste une couche de difficulté supplémentaire inutile dans la plupart des cas.
Fil d'interface utilisateur
Il est vrai que cela doit être appelé à partir du thread d'interface utilisateur. D'autres réponses contiennent des exemples sur la façon d'y parvenir. Cependant, cela n'est requis que si vous travaillez sur ces informations en dehors du thread d'interface utilisateur. Cela provient d'un service ou d'un thread non UI. Dans des cas simples, vous mettrez à jour vos données à partir d'un clic sur un bouton ou d'une autre activité / fragment. Donc toujours dans le thread d'interface utilisateur. Pas besoin de toujours insérer ce runOnUiTrhead.
Exemple de projet rapide
Peut être trouvé à https://github.com/hanscappelle/so-2250770.git . Il vous suffit de cloner et d'ouvrir le projet dans Android Studio (gradle). Ce projet a un bâtiment MainAcitivity
ListView
avec toutes les données aléatoires. Cette liste peut être actualisée à l'aide du menu d'action.L'implémentation de l'adaptateur que j'ai créée pour cet exemple ModelObject expose la collecte de données
Code de la MainActivity
Plus d'information
Un autre bon article sur la puissance de listViews se trouve ici: http://www.vogella.com/articles/AndroidListView/article.html
la source
adapter.clear()
, j'appelle maintenant , etadapter.addAll(Array<T>)
avant d'appelernotifyDataSetChanged()
Appelez runnable quand vous le souhaitez:
OnCreate()
, vous définissez votre thread exécutable:la source
runOnUiThread()
fonction.run = new Runnable()
et ai juste donné à ma fonction unepublic void refreshUIThread()
méthode qui modélise votrerun()
méthode (qui fonctionne aussi).J'ai eu quelques problèmes avec l'actualisation dynamique de ma liste.
notifyDataSetChanged () ne fonctionnait pas correctement dans mon cas [j'ai appelé le notifyDataSetChanged d'une autre classe]. Juste au cas où j'ai édité le ListView dans l'activité en cours (Thread). Cette vidéo grâce à Christopher a donné l'ultime indice.
Dans ma deuxième classe, j'ai utilisé
pour accéder à la mise à jour () de mon Activité. Cette mise à jour comprend
pour indiquer à l'adaptateur d'actualiser la vue. A bien fonctionné pour autant que je puisse dire.
la source
Si vous utilisez SimpleCursorAdapter, essayez d'appeler requery () sur l'objet Cursor.
la source
si vous n'êtes pas encore satisfait de l'actualisation de ListView, vous pouvez consulter cet extrait, c'est pour charger la listView à partir de la base de données.En réalité, ce que vous avez à faire est simplement de recharger ListView, après avoir effectué une opération CRUD, ce n'est pas le meilleur moyen de mais il actualisera le ListView comme vous le souhaitez.
Cela fonctionne pour moi .... si vous trouvez une meilleure solution, veuillez partager ...
la source
Les solutions proposées par les personnes dans ce post fonctionnent ou non en fonction principalement de la version Android de votre appareil. Par exemple, pour utiliser la méthode AddAll, vous devez mettre android: minSdkVersion = "10" dans votre appareil Android.
Pour résoudre ces questions pour tous les appareils, j'ai créé ma propre méthode dans mon adaptateur et j'utilise à l'intérieur de la méthode d'ajout et de suppression héritée d'ArrayAdapter qui met à jour vos données sans problème.
Mon code: en utilisant ma propre classe de données RaceResult, vous utilisez votre propre modèle de données.
ResultGpRowAdapter.java
ResultsGp.java
la source
Si vous souhaitez conserver votre position de défilement lorsque vous actualisez, et vous pouvez le faire:
Pour les informations détaillées, veuillez consulter Android ListView: conservez votre position de défilement lorsque vous actualisez .
la source
Utilisez simplement à l'
myArrayList.remove(position);
intérieur d'un écouteur:la source
Vous devez utiliser un seul objet de cette liste dont les données que vous gonflez
ListView
. Si la référence est modifiée,notifyDataSetChanged()
cela ne fonctionne pas. Chaque fois que vous supprimez des éléments de la liste, supprimez-les également de la liste que vous utilisez, qu'il s'agisse d'une liste de tableaux <> ou de quelque chose d'autre, puis appelez unnotifyDataSetChanged()
objet de votre classe d'adaptateur.Alors, voici comment je l'ai géré dans mon adaptateur, voir ci-dessous
la source
Après avoir supprimé les données de la liste, vous devez appeler
refreshDrawableState()
. Voici l'exemple:et la
deleteContact
méthode enDatabaseHelper
classe ressemblera un peula source
Je n'ai pas pu obtenir notifyDataSetChanged () pour travailler sur la mise à jour de mon SimpleAdapter, j'ai donc essayé de supprimer d'abord toutes les vues qui étaient attachées à la disposition parent à l'aide de removeAllViews (), puis d'ajouter ListView, et cela a fonctionné, ce qui m'a permis de mettre à jour le UI:
la source
Pour moi, après avoir modifié les informations dans la base de données SQL, rien ne pouvait actualiser la vue de liste (pour être une vue de liste expansible spécifique), donc si notifyDataSetChanged () ne vous aide pas, vous pouvez essayer de vider votre liste en premier et de l'ajouter à nouveau après cet appel notifyDataSetChanged (). Par exemple
J'espère que cela a du sens pour vous.
la source
lors de l'utilisation de SimpleCursorAdapter peut appeler changeCursor (newCursor) sur l'adaptateur.
la source
J'étais le même lorsque, dans un fragment, j'ai voulu remplir un ListView (dans un seul TextView) avec l'adresse mac des appareils BLE scannés pendant un certain temps.
Ce que j'ai fait, c'est ceci:
Ensuite, le ListView a commencé à se remplir dynamiquement avec l'adresse mac des appareils trouvés.
la source
Je pense que cela dépend de ce que vous entendez par rafraîchissement. Voulez-vous dire que l'affichage de l'interface graphique doit être actualisé, ou voulez-vous dire que les vues enfant doivent être actualisées de sorte que vous pouvez appeler par programme getChildAt (int) et obtenir la vue correspondant à ce qui se trouve dans l'adaptateur.
Si vous souhaitez que l'affichage de l'interface graphique soit actualisé, appelez notifyDataSetChanged () sur l'adaptateur. L'interface graphique sera actualisée lors du prochain redessin.
Si vous voulez pouvoir appeler getChildAt (int) et obtenir une vue qui reflète ce qui se trouve dans l'adaptateur, appelez alors layoutChildren (). Cela entraînera la reconstruction de la vue enfant à partir des données de l'adaptateur.
la source
J'avais une ArrayList que je voulais afficher dans une liste. ArrayList contenait des éléments de mysql. J'ai remplacé la méthode onRefresh et dans cette méthode, j'ai utilisé tablelayout.removeAllViews (); puis répété le processus d'obtention à nouveau des données de la base de données. Mais avant cela, assurez-vous d'effacer votre ArrayList ou toute autre structure de données, sinon de nouvelles données seront ajoutées à l'ancienne.
la source
Si vous souhaitez mettre à jour la liste de l'interface utilisateur à partir d'un service, rendez l'adaptateur statique dans votre activité principale et procédez comme suit:
la source
Si vous utilisez des lignes de guidage Android et que vous utilisez
ContentProviders
pour obtenir des donnéesDatabase
et que vous les affichez à l'ListView
aide deCursorLoader
etCursorAdapters
, alors toutes les modifications apportées aux données associées seront automatiquement reflétées dans ListView.Votre
getContext().getContentResolver().notifyChange(uri, null);
curseurContentProvider
sera suffisant pour refléter les changements. Pas besoin de travail supplémentaire.Mais lorsque vous ne les utilisez pas tous, vous devez indiquer à l'adaptateur lorsque l'ensemble de données change. Vous devez également repeupler / recharger votre jeu de données (par exemple, la liste), puis vous devez appeler
notifyDataSetChanged()
l'adaptateur.notifyDataSetChanged()
ne fonctionnera pas s'il n'y a pas de changements dans le jeu de données. Voici le commentaire au-dessus de la méthode dans docs-la source
Je n'ai pu obtenir notifyDataSetChanged qu'en obtenant de nouvelles données d'adaptateur, puis en réinitialisant l'adaptateur pour la vue de liste, puis en effectuant l'appel comme suit:
la source
sur une autre option est la
onWindowFocusChanged
méthode, mais bien sûr, elle est sensible et a besoin d'un codage supplémentaire pour qui est intéresséla source
Considérez que vous avez transmis une liste à votre adaptateur.
Utilisation:
list.getAdapter().notifyDataSetChanged()
pour mettre à jour votre liste.
la source
Si j'ai parlé de mon scénario ici, aucune des réponses ci-dessus ne fonctionnera parce que j'ai eu une activité qui affiche la liste des valeurs de base de données avec un bouton de suppression et lorsqu'un bouton de suppression est enfoncé, je voulais supprimer cet élément de la liste.
Le truc cool, c'est que je n'ai pas utilisé la vue recycleur mais une simple vue liste et cette vue liste initialisée dans la classe adaptateur. Ainsi, l'appel à
notifyDataSetChanged()
ne fera rien à l'intérieur de la classe d'adaptateur et même dans la classe d'activité où l'objet adaptateur est initialisé car la méthode delete était dans la classe d'adaptateur.Ainsi, la solution était de supprimer l'objet de l'adaptateur dans la
getView
méthode de classe d'adaptateur (pour supprimer uniquement cet objet spécifique mais si vous souhaitez tout supprimer, appelezclear()
).Pour vous faire une idée, à quoi ressemblait mon code,
Remarque: ici
remove()
et lesgetItem()
méthodes sont héritées de la classe Adapter.remove()
- pour supprimer l'élément spécifique qui est cliquégetItem(position)
- est d'obtenir l'élément (ici, c'est mon objet Word que j'ai ajouté à la liste) à partir de la position cliquée.Voici comment j'ai défini l'adaptateur sur la liste dans la classe d'activité,
la source
Le plus simple est de simplement créer une nouvelle couche et de déposer l'ancienne:
la source