Lorsque je repeuple mon ListView
, j'appelle une méthode spécifique de mon Adapter
.
Problème :
Lorsque j'appelle updateReceiptsList
depuis mon Adapter
, les données sont actualisées, mais mon ListView
ne reflète pas le changement.
Question :
Pourquoi mon ListView
affiche-t-il les nouvelles données lorsque j'appelle notifyDataSetChanged
?
Adaptateur :
public class ReceiptListAdapter extends BaseAdapter {
public List<Receipt> receiptlist;
private Context context;
private LayoutInflater inflater;
private DateHelpers dateH;
public ReceiptListAdapter(Activity activity, Context mcontext, List<Receipt> rl) {
context = mcontext;
receiptlist = rl;
Collections.reverse(receiptlist);
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
dateH = new DateHelpers();
}
@Override
public int getCount() {
try {
int size = receiptlist.size();
return size;
} catch(NullPointerException ex) {
return 0;
}
}
public void updateReceiptsList(List<Receipt> newlist) {
receiptlist = newlist;
this.notifyDataSetChanged();
}
@Override
public Receipt getItem(int i) {
return receiptlist.get(i);
}
@Override
public long getItemId(int i) {
return receiptlist.get(i).getReceiptId() ;
}
private String getPuntenString(Receipt r) {
if(r.getPoints().equals("1")) {
return "1 punt";
}
return r.getPoints()+" punten";
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
final Receipt receipt = receiptlist.get(position);
ReceiptViewHolder receiptviewholder;
Typeface tf_hn = Typeface.createFromAsset(context.getAssets(), "helveticaneue.ttf");
Typeface tf_hn_bold = Typeface.createFromAsset(context.getAssets(), "helveticaneuebd.ttf");
if (vi == null) { //convertview==null
receiptviewholder = new ReceiptViewHolder();
vi = inflater.inflate(R.layout.view_listitem_receipt, null);
vi.setOnClickListener(null);
vi.setOnLongClickListener(null);
vi.setLongClickable(false);
receiptviewholder.shop = (TextView) vi.findViewById(R.id.tv_listitemreceipt_shop);
receiptviewholder.date = (TextView) vi.findViewById(R.id.tv_listitemreceipt_date);
receiptviewholder.price = (TextView) vi.findViewById(R.id.tv_listitemreceipt_price);
receiptviewholder.points = (TextView) vi.findViewById(R.id.tv_listitemreceipt_points);
receiptviewholder.shop.setTypeface(tf_hn_bold);
receiptviewholder.price.setTypeface(tf_hn_bold);
vi.setTag(receiptviewholder);
}else{//convertview is not null
receiptviewholder = (ReceiptViewHolder)vi.getTag();
}
receiptviewholder.shop.setText(receipt.getShop());
receiptviewholder.date.setText(dateH.timestampToDateString(Long.parseLong(receipt.getPurchaseDate())));
receiptviewholder.price.setText("€ "+receipt.getPrice());
receiptviewholder.points.setText(getPuntenString(receipt));
vi.setClickable(false);
return vi;
}
public static class ReceiptViewHolder {
public TextView shop;
public TextView date;
public TextView price;
public TextView points;
}
public Object getFilter() {
// XXX Auto-generated method stub
return null;
}
}
--ÉDITER:
solution de contournement trouvée
Juste pour avoir du code fonctionnel que je fais maintenant:
listview.setAdapter( new ReceiptListAdapter(activity,mcontext, -new dataset-);
Fonctionne, mais pas comment il est censé fonctionner.
Réponses:
Changez votre méthode de
À
Vous conservez donc le même objet que votre DataSet dans votre adaptateur.
la source
ReceiptListObject
au lieu d'unList
objet, que pouvez-vous faire alors pour résoudre ce problème?BaseAdapter
et cet adaptateur ne sait pas à quelles données il est lié ... donc si j'ai un objet personnalisé et que j'utilise des fonctions personnalisées de cet objet (commecustObject.getCount()
etcustObject.getChildAt(int i)
par exemple), et que je souhaite échanger cet objet, celanotifyDataSetChanged
ne fonctionne pas ... de toute façon, je pense que ce problème ne se produit jamais avec unArrayAdapter
J'ai le même problème et je m'en rends compte. Lorsque nous créons l'adaptateur et le définissons sur listview, listview pointera vers l'objet quelque part dans la mémoire que l'adaptateur contient, les données de cet objet s'afficheront dans listview.
si nous créons à nouveau un objet pour adaptateur avec une autre donnée et notifydatasetchanged ():
cela n'affectera pas les données dans la vue de liste car la liste pointe vers un objet différent, cet objet ne sait rien sur le nouvel objet dans l'adaptateur et notifyDataSetChanged () n'affecte rien. Nous devons donc modifier les données dans l'objet et éviter de créer à nouveau un nouvel objet pour l'adaptateur
la source
Comme je l'ai déjà expliqué les raisons de ce problème et comment le gérer dans un fil de réponse différent ici . Je partage toujours le résumé de la solution ici.
L'une des principales raisons
notifyDataSetChanged()
ne fonctionnera pas pour vous - est,Votre adaptateur perd la référence à votre liste .
Lors de la création et de l'ajout d'une nouvelle liste au fichier
Adapter
. Suivez toujours ces directives:arrayList
while en le déclarant globalement.arrayList
il s'en chargera, mais ne perdra jamais la référence.adapter.clear()
etarrayList.clear()
avant d' ajouter des données réellement à la liste) , mais ne définissez pas l' adaptateur IE Si les nouvelles données est renseigné dans learrayList
pas seulementadapter.notifyDataSetChanged()
J'espère que cela t'aides.
la source
Essayez peut-être de rafraîchir votre ListView:
receiptsListView.invalidate()
.EDIT: Une autre pensée m'est venue à l'esprit. Pour mémoire, essayez de désactiver le cache de vue de liste:
la source
J'ai eu le même problème en utilisant
ListAdapter
Je laisse Android Studio implémenter des méthodes pour moi et voici ce que j'ai obtenu:
Le problème est que ces méthodes n'appellent pas d'
super
implémentations etnotifyDataSetChange
ne sont donc jamais appelées.Supprimez ces remplacements manuellement ou ajoutez des super appels et cela devrait fonctionner à nouveau.
la source
Tu peux essayer. Ça marche pour moi
la source
Si
adapter
est défini surAutoCompleteTextView
alorsnotifyDataSetChanged()
ne fonctionne pas.Besoin de ceci pour mettre à jour l'adaptateur:
Reportez-vous: http://android-er.blogspot.in/2012/10/autocompletetextview-with-dynamic.html
la source
Si, par hasard, vous avez atterri sur ce fil et vous vous demandez pourquoi
adapter.invaidate()
ou desadapter.clear()
méthodes ne sont pas présentes dans votre cas, peut-être parce que vous utilisez peut-être à laRecyclerView.Adapter
place deBaseAdapter
ce qui est utilisé par le demandeur de cette question. Si vous effacezlist
ouarraylist
ne résolvez pas votre problème, il se peut que vous créiez au moins deux instances duadapter
par exemple:Activité principale
et
SomeFragment
Si, dans le second cas, vous attendez un changement dans la liste des vues gonflées dans la vue du recycleur, cela ne se produira pas comme dans la deuxième fois, une nouvelle instance du
adapter
est créée qui n'est pas attachée à la vue du recycleur. La configurationnotifyDataSetChanged
du deuxième adaptateur ne changera pas le contenu de la vue du récupérateur. Pour cela, créez une nouvelle instance de la vue recycleur dans SomeFragment et attachez-la à la nouvelle instance de l'adaptateur.Certains Fragment
Cependant, je ne recommande pas de créer plusieurs instances de la même vue d'adaptateur et de recycleur.
la source
Ajoutez ce code
la source
J'ai le même problème mais je viens de le terminer !!
tu devrais changer pour
la source
Mon cas était différent mais ça pourrait être le même cas pour d'autres
pour ceux qui n'ont toujours pas trouvé de solution et ont tout essayé ci-dessus, si vous utilisez l'adaptateur à l'intérieur du fragment, la raison pour laquelle cela ne fonctionne pas
fragment could be recreating so the adapter is recreating everytime the fragment recreate
vous devez vérifier si l'adaptateur et la liste des objets sont nuls avant de l'initialiser
la source