Wenn ich meine wieder auffülle ListView
, rufe ich eine bestimmte Methode von meiner auf Adapter
.
Problem :
Wenn ich updateReceiptsList
von meinem aus anrufe Adapter
, werden die Daten aktualisiert, aber mein ListView
spiegelt die Änderung nicht wider.
Frage :
Warum werden meine ListView
neuen Daten nicht angezeigt , wenn ich anrufe notifyDataSetChanged
?
Adapter :
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;
}
}
--BEARBEITEN:
Workaround gefunden
Nur um einen Funktionscode zu haben, den ich jetzt mache:
listview.setAdapter( new ReceiptListAdapter(activity,mcontext, -new dataset-);
Funktioniert, aber nicht wie es funktionieren soll.
Antworten:
Ändern Sie Ihre Methode von
Zu
Sie behalten also dasselbe Objekt wie Ihr DataSet in Ihrem Adapter.
quelle
ReceiptListObject
anstelle einesList
von Objekten haben möchten. Was können Sie dann tun, um dieses Problem zu lösen?BaseAdapter
und dieser Adapter weiß nicht, an welche Daten er gebunden ist. Wenn ich also ein benutzerdefiniertes Objekt habe und benutzerdefinierte Funktionen dieses Objekts (wiecustObject.getCount()
undcustObject.getChildAt(int i)
zum Beispiel) verwende und dieses Objekt austauschen möchte, funktioniert diesnotifyDataSetChanged
nicht ... sowieso denke ich, dass dieses Problem nie mit einemArrayAdapter
Ich habe das gleiche Problem und das merke ich. Wenn wir einen Adapter erstellen und auf Listenansicht setzen, zeigt die Listenansicht auf ein Objekt im Speicher, das der Adapter enthält. Die Daten in diesem Objekt werden in der Listenansicht angezeigt.
Wenn wir erneut ein Objekt für den Adapter mit anderen Daten erstellen und notifydatasetchanged ():
Dies wirkt sich nicht auf Daten in der Listenansicht aus, da die Liste auf ein anderes Objekt verweist, dieses Objekt nichts über neue Objekte im Adapter weiß und notifyDataSetChanged () keine Auswirkungen hat. Wir sollten also die Daten im Objekt ändern und vermeiden, erneut ein neues Objekt für den Adapter zu erstellen
quelle
Wie ich bereits erklärt habe, die Gründe für dieses Problem und auch, wie man damit umgeht, in einem anderen Antwort-Thread hier . Trotzdem teile ich hier die Lösungszusammenfassung.
Einer der Hauptgründe, warum Sie
notifyDataSetChanged()
nicht arbeiten, ist:Ihr Adapter verliert den Verweis auf Ihre Liste .
Beim Erstellen und Hinzufügen einer neuen Liste zur
Adapter
. Befolgen Sie immer diese Richtlinien:arrayList
während Sie es global deklarieren.arrayList
, darum kümmert, aber niemals die Referenz verliert.adapter.clear()
undarrayList.clear()
bevor Sie tatsächlich Daten zur Liste hinzufügen), aber stellen Sie den Adapter nicht ein, dh wenn die neuen Daten in derarrayList
als nur gefüllt sindadapter.notifyDataSetChanged()
Hoffe das hilft.
quelle
Versuchen Sie möglicherweise, Ihre ListView zu aktualisieren:
receiptsListView.invalidate()
.EDIT: Ein anderer Gedanke kam mir in den Sinn. Versuchen Sie nur für den Datensatz, den Listenansichts-Cache zu deaktivieren:
quelle
Ich hatte das gleiche Problem mit
ListAdapter
Ich habe Android Studio Methoden für mich implementieren lassen und Folgendes habe ich:
Das Problem ist, dass diese Methoden keine
super
Implementierungen aufrufen und dahernotifyDataSetChange
niemals aufgerufen werden.Entfernen Sie diese Überschreibungen entweder manuell oder fügen Sie Superaufrufe hinzu, und es sollte wieder funktionieren.
quelle
Du kannst es versuchen. Es funktioniert für mich
quelle
Wenn
adapter
gesetzt wirdAutoCompleteTextView
dannnotifyDataSetChanged()
nicht funktioniert.Benötigen Sie dies, um den Adapter zu aktualisieren:
Siehe: http://android-er.blogspot.in/2012/10/autocompletetextview-with-dynamic.html
quelle
Wenn Sie zufällig auf diesem Thread gelandet sind und sich gefragt haben, warum
adapter.invaidate()
oderadapter.clear()
Methoden in Ihrem Fall nicht vorhanden sind, dann möglicherweise, weil Sie möglicherweiseRecyclerView.Adapter
stattdessenBaseAdapter
verwenden, welche vom Fragesteller dieser Frage verwendet wird. Wenn Sie das Problem behebenlist
oderarraylist
nicht lösen, kann es vorkommen, dass Sie zwei oder mehr Instanzen des Beispielsadapter
erstellen:Hauptaktivität
und
SomeFragment
Wenn Sie im zweiten Fall eine Änderung in der Liste der aufgeblasenen Ansichten in der Recycler-Ansicht erwarten, geschieht dies nicht, da beim zweiten Mal eine neue Instanz von
adapter
erstellt wird, die nicht an die Recycler-Ansicht angehängt ist. Durch die EinstellungnotifyDataSetChanged
im zweiten Adapter wird der Inhalt der Recycling-Ansicht nicht geändert. Erstellen Sie dazu eine neue Instanz der Recycler-Ansicht in SomeFragment und hängen Sie sie an die neue Instanz des Adapters an.SomeFragment
Ich empfehle jedoch nicht, mehrere Instanzen desselben Adapters und derselben Recycler-Ansicht zu erstellen.
quelle
Fügen Sie diesen Code hinzu
quelle
Ich habe das gleiche Problem, aber ich habe es gerade beendet !!
du solltest zu wechseln
quelle
Mein Fall war anders, aber für andere könnte es der gleiche sein
Für diejenigen, die immer noch keine Lösung finden und alles oben Genannte ausprobieren konnten: Wenn Sie den Adapter im Fragment verwenden, ist dies der Grund, warum er nicht funktioniert
fragment could be recreating so the adapter is recreating everytime the fragment recreate
Sie sollten vor der Initialisierung überprüfen, ob der Adapter und die Objektliste null sind
quelle