Als ik mijn ListView
opnieuw vul, roep ik een specifieke methode aan vanuit mijn adapter
.
Probleem:
Als ik updateReceiptsList
aanroep vanuit mijn adapter
, worden de gegevens vernieuwd, maar mijn ListView
geeft de wijziging niet weer.
Vraag:
Waarom toont mijn ListView
de nieuwe gegevens niet wanneer ik notifyDataSetChanged
aanroep?
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;
}
}
–EDIT:
oplossing gevonden
Gewoon om wat functionele code te hebben die ik nu heb:
listview.setAdapter( new ReceiptListAdapter(activity,mcontext, -new dataset-);
Werkt, maar niet hoe het zou moeten werken.
Antwoord 1, autoriteit 100%
Wijzig uw methode van
public void updateReceiptsList(List<Receipt> newlist) {
receiptlist = newlist;
this.notifyDataSetChanged();
}
Naar
public void updateReceiptsList(List<Receipt> newlist) {
receiptlist.clear();
receiptlist.addAll(newlist);
this.notifyDataSetChanged();
}
U behoudt dus hetzelfde object als uw DataSet in uw Adapter.
Antwoord 2, autoriteit 7%
Ik heb hetzelfde probleem en dat besef ik. Wanneer we een adapter maken en deze instellen op lijstweergave, zal lijstweergave verwijzen naar een object ergens in het geheugen dat in de adapter past, gegevens in dit object worden weergegeven in lijstweergave.
adapter = new CustomAdapter(data);
listview.setadapter(adapter);
als we opnieuw een object voor adapter maken met andere gegevens en notificeren datasetchanged():
adapter = new CustomAdapter(anotherdata);
adapter.notifyDataSetChanged();
Dit heeft geen invloed op gegevens in Listview omdat de lijst naar een ander object wijst, dit object weet niets van een nieuw object in de adapter, en opmerkt niet-opmerkt () invloed op niets.
Dus we moeten gegevens in het object wijzigen en voorkomen om opnieuw een nieuw object te maken voor adapter
3, Autoriteit 5%
Zoals ik al de redenen achter deze kwestie heb uitgelegd en ook hoe om te gaan in een andere antwoorddraad hier . Toch deel ik hier de Solution Samenvatting.
Een van de belangrijkste redenen notifyDataSetChanged()
Werkt niet voor u – is,
Uw adapter verliest verwijzing naar uw lijst .
Bij het maken en toevoegen van een nieuwe lijst aan de adapter
. Volg altijd deze richtlijnen:
- Initialiseer de
arrayList
terwijl u het wereldwijd verklaart. - Voeg de lijst rechtstreeks toe aan de adapter zonder controle op null en leeg
waarden . Stel de adapter rechtstreeks in op de lijst (controleer niet op elk
voorwaarde). Adapter garandeert u dat waar u ook bent
Wijzigingen in de gegevens van dearrayList
het zal ervoor zorgen, maar verliest nooit de
referentie. - Wijzig altijd de gegevens in de Arraypagina zelf (als uw gegevens volledig nieuw zijn
Dan kunt uadapter.clear()
enarrayList.clear()
vóór
Eigenlijk gegevens toevoegen aan de lijst) maar stel de adapter niet in I.E in als
De nieuwe gegevens worden ingevuld in dearrayList
dan alleen
adapter.notifyDataSetChanged()
Ik hoop dat dit helpt.
4
Probeer misschien uw lijstweergave te vernieuwen:
receiptsListView.invalidate()
.
EDIT: Een andere gedachte kwam in mijn gedachten. Probeer alleen voor het record te schakelen Lijstweergave Cache uit te schakelen:
<ListView
...
android:scrollingCache="false"
android:cacheColorHint="@android:color/transparent"
... />
5
Ik had hetzelfde probleem met behulp van ListAdapter
Ik laat Android Studio methoden voor mij implementeren en dit is wat ik kreeg:
public class CustomAdapter implements ListAdapter {
...
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
...
}
Het probleem is dat deze methoden niet bellen met super
Implementations, dus notifyDataSetChange
wordt nooit gebeld.
Verwijder deze overrides handmatig of voeg Super-oproepen toe en het zou opnieuw moeten werken.
@Override
public void registerDataSetObserver(DataSetObserver observer) {
super.registerDataSetObserver(observer);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
super.unregisterDataSetObserver(observer);
}
6
class StudentAdapter extends BaseAdapter {
ArrayList<LichHocDTO> studentList;
private void capNhatDuLieu(ArrayList<LichHocDTO> list){
this.studentList.clear();
this.studentList.addAll(list);
this.notifyDataSetChanged();
}
}
U kunt het proberen. Het werkt voor mij
7
Indien adapter
is ingesteld op AutoCompleteTextView
Dan notifyDataSetChanged()
werkt niet.
Heeft u dit nodig om de adapter bij te werken:
myAutoCompleteAdapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_dropdown_item_1line, myList);
myAutoComplete.setAdapter(myAutoCompleteAdapter);
Zie: http: //android-er.blogspot .In / 2012/10 / autocompletetExtview-with-dynamic.html
8
Voeg deze code toe
runOnUiThread(new Runnable() { public void run() {
adapter = new CustomAdapter(anotherdata);
adapter.notifyDataSetChanged();
}
});
9
Als je door een kans op deze thread hebt geland en je afvraagt waarom adapter.invaidate()
of adapter.clear()
Methods zijn niet aanwezig in jouw zaak, dan Misschien gebruik je RecyclerView.Adapter
in plaats van BaseAdapter
die wordt gebruikt door de vraager van deze vraag. Als het opruimen van de list
of arraylist
Niet oplossen van uw probleem, kan het mogelijk gebeuren dat u twee of meer instanties van de adapter
voor ex.:
Maatactiviteit
...
adapter = new CustomAdapter(list);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
...
en
somefragment
...
adapter = new CustomAdapter(newList);
adapter.notifyDataSetChanged();
...
Als u in het tweede geval een wijziging verwacht in de lijst met opgeblazen weergaven in de recycler-weergave, dan zal dit niet gebeuren, aangezien in de tweede keer een nieuwe instantie van de adapter
wordt gemaakt die niet gekoppeld aan de weergave van de recycler. Het instellen van notifyDataSetChanged
in de tweede adapter zal de inhoud van de recycerweergave niet veranderen. Maak daarvoor een nieuwe instantie van de recycler-weergave in SomeFragmenten koppel deze aan de nieuwe instantie van de adapter.
SomeFragment
...
recyclerView = new RecyclerView();
adapter = new CustomAdapter();
recyclerView.setAdapter(adapter);
...
Hoewel ik niet aanraad om meerdere instanties van dezelfde adapter- en recyclerweergave te maken.
Antwoord 10
In mijn geval vergeet ik gewoon om in mijn fragment mRecyclerView.setAdapter(adapter)
toe te voegen
Antwoord 11
Ik heb een zeer noob-fout gemaakt dat ik de adapter van RecyclerView aan het instellen was voordat ik de adapter zelf op deze manier initialiseerde.
// Assuume oneOffJobTasksListRVAdapter is declared already
recyclerView.setAdapter(oneOffJobTasksListRVAdapter);
oneOffJobTasksListRVAdapter = new OneOffJobTasksListRVAdapter();
Het verwisselen van de lijnen loste mijn probleem op.
oneOffJobTasksListRVAdapter = new OneOffJobTasksListRVAdapter();
recyclerView.setAdapter(oneOffJobTasksListRVAdapter);
Antwoord 12
Ik heb hetzelfde probleem
maar ik heb het net uit!!
je moet veranderen in
public class ReceiptListAdapter extends BaseAdapter {
public List<Receipt> receiptlist;
private Context context;
private LayoutInflater inflater;
private DateHelpers dateH;
private List<ReceiptViewHolder> receiptviewlist;
public ReceiptListAdapter(Activity activity, Context mcontext, List<Receipt> rl) {
context = mcontext;
receiptlist = rl;
receiptviewlist = new ArrayList<>();
receiptviewlist.clear();
for(int i = 0; i < receiptlist.size(); i++){
ReceiptViewHolder receiptviewholder = new ReceiptViewHolder();
receiptviewlist.add(receiptviewholder);
}
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 receiptviewholder = receiptviewlist.get(position);
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;
}
}