notifyDataSetChange werkt niet vanaf aangepaste adapter

Als ik mijn ListViewopnieuw vul, roep ik een specifieke methode aan vanuit mijn adapter.

Probleem:

Als ik updateReceiptsListaanroep vanuit mijn adapter, worden de gegevens vernieuwd, maar mijn ListViewgeeft de wijziging niet weer.

Vraag:

Waarom toont mijn ListViewde nieuwe gegevens niet wanneer ik notifyDataSetChangedaanroep?

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:

  1. Initialiseer de arrayListterwijl u het wereldwijd verklaart.
  2. 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 de arrayListhet zal ervoor zorgen, maar verliest nooit de
    referentie.
  3. Wijzig altijd de gegevens in de Arraypagina zelf (als uw gegevens volledig nieuw zijn
    Dan kunt u adapter.clear()en arrayList.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 de arrayListdan 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 superImplementations, dus notifyDataSetChangewordt 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 adapteris ingesteld op AutoCompleteTextViewDan 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.Adapterin plaats van BaseAdapterdie wordt gebruikt door de vraager van deze vraag. Als het opruimen van de listof arraylistNiet oplossen van uw probleem, kan het mogelijk gebeuren dat u twee of meer instanties van de adaptervoor 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 adapterwordt gemaakt die niet gekoppeld aan de weergave van de recycler. Het instellen van notifyDataSetChangedin 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;
    }
}

Other episodes