Search code examples
javaandroidlistviewandroid-arrayadapter

Can't access ArrayAdapter from AlertDialog


TL;DR

I don't understand how to change my ArrayList dataset from a dialog so that it updates my listview. My current solution crashes because the ListView doesn't update. Need to know where my code is going wrong.

The Problem

I have one activity that has a ListView of items with an ArrayAdapter that connects it to my data (ArrayList). When a user clicks on an item in that list I load an AlertDialog that allows the user to delete that item. Debugging shows that the item does get removed from the data, the dialog closes as expected but the ListView doesn't update and subsequent clicks cause the app to crash.

The problem seems to be tied to the itemsList.notifyDataSetChanged();. I've tried hitting the adapter instead but then the Adapter itself can't be resolved.

I know this is due to an error on my part but I can't find where I'm going wrong.

The Code

ScannerActivity.java

import android.content.Intent;
import android.graphics.pdf.PdfDocument;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class ScannerActivity extends AppCompatActivity {

Button delete, deleteAll, manual, export, newPull;
EditText input_main;
static int pulls = 001;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_scanner);


    //Load some items for testing
    final PullSheet pullSheet = new PullSheet();
    pullSheet.createSheet(nameText, roleText, storeText, runitText);
    pullSheet.addItem("12543", 5);
    pullSheet.addItem("3526", 1);
    pullSheet.addItem("00045", 3);
    pullSheet.addItem("95462", 18);
    pullSheet.addItem("1181", 53);
    pullSheet.addItem("6543", 1);

    final ArrayAdapter<PullItem> itemAdapter =
            new ArrayAdapter<PullItem>(this, 0, pullSheet.SheetItems) {
                @Override
                public View getView(int position,
                                    View convertView,
                                    ViewGroup parent){
                    PullItem currentItem = getItem(position);//

                    if(convertView == null) {
                        convertView = getLayoutInflater()
                                .inflate(R.layout.item, null, false);
                    }

                    TextView itemSku =
                            (TextView)convertView.findViewById(R.id.item_sku);
                    TextView itemQty =
                            (TextView)convertView.findViewById(R.id.item_qty);

                    itemSku.setText(currentItem.sku);
                    itemQty.setText(String.valueOf(currentItem.qty));

                    return convertView;
                }
            };

    final ListView itemsList = (ListView) findViewById(R.id.itemsList);
    itemsList.setAdapter(itemAdapter);

    itemsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(final AdapterView<?> itemAdapter,
                                View view, int position, long rowId) {

            final PullItem item = pullSheet.SheetItems.get(position);
            final PullSheet sheet = pullSheet;

            //load dialog
            final AlertDialog.Builder mBuilder = new AlertDialog.Builder(ScannerActivity.this);
            final View mView = getLayoutInflater().inflate(R.layout.dialog_interact, null);

            //Declare dialog ui elements
            Button mYes = (Button) mView.findViewById(R.id.btnYes);
            Button mNo = (Button) mView.findViewById(R.id.btnNo);
            TextView skuData = (TextView) mView.findViewById(R.id.skuData);
            TextView qtyData = (TextView) mView.findViewById(R.id.qtyData);

            skuData.setText(item.sku);
            qtyData.setText(item.qty.toString());


            mBuilder.setView(mView);
            final AlertDialog dialog = mBuilder.create();
            dialog.show();

            mYes.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    deletePullItem(sheet, item);
                    itemsList.notifyDataSetChanged();// This isn't working, "Cannot resolve method notifyDataSetChanged()"
                    dialog.dismiss();
                }
            });
            mNo.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });
        }
    });
    }

    public void deletePullItem(PullSheet sheet, PullItem item)
    {
        sheet.removeItem(item);
    }

} 

PullSheet.java

import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.UUID;

public class PullSheet extends Application{

protected String pullerName;
protected String role;
protected String store;
protected String sheetId;
protected String runItId;
protected Long startTime = System.currentTimeMillis();
protected ArrayList<PullItem> SheetItems = new ArrayList<PullItem>();


public void createSheet(String _pullerName, String _role, String _store, String _runItId){
    setPullerName(_pullerName);
    setRole(_role);
    setStore(_store);
    setRunItId(_runItId);
    setSheetId();
}

protected void addItem(String sku, Integer qty){
    SheetItems.add(new PullItem(sku, qty));
}
protected void removeItem(PullItem item){
    this.SheetItems.remove(item);
}

//Getters and setters

public String getPullerName(){ return pullerName; }
public String getRole(){
    return role;
}
public String getStore(){
    return store;
}
public String getRunItId(){
    return runItId;
}
public String getSheetId(){
    return sheetId;
}
public Long getStartTime(){
    return startTime;
}


private void setPullerName(String _pullerName){ pullerName = _pullerName; }
private void setRole(String _role){ pullerName = _role; }
private void setStore(String _store){ store = _store; }
private void setRunItId(String _runItId){ runItId = _runItId; }

private void setSheetId(){
    SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
    String dateString = formatter.format(new Date(startTime));

    UUID uuid = UUID.randomUUID();
    String randUUID = uuid.toString();

    sheetId = dateString + "-" + this.pullerName + "-" + randUUID + "-" + runItId;

  }
}

PullItem.java

public class PullItem {

    protected String sku;
    protected Integer qty;

    public PullItem(String sku, Integer qty) {
        setSku(sku);
        this.qty = 1;
    }


    String getSku(){ return sku; }
    Integer getQty(){ return qty; }

    void setSku(String _sku){ sku = _sku; }
    void setQty(Integer _qty){ qty = _qty; }
    void incrementQty(){ qty += 1; }
}

The Solution

I need to be told where I'm going wrong. I know it has to do with the ArrayAdapter and the ListView, but Everything I've tried just moves the "Can't resolve" to another part of the expression.

Thanks in advance for any help


Solution

  • notifyDatasetChanged() is an Adapter method, so you can't use it with ListView

    But this should work:

    Make your Adapter a member variable (instantiate it the way you did) so you can access it everywhere in the Activity:

    private ArrayAdapter<PullItem> itemAdapter;
    

    Simply call deletePullItem() if the user clicks the OK-Button:

    mYes.setOnClickListener(new View.OnClickListener() {   
       @Override
       public void onClick(View v) {
            deletePullItem(sheet, item);
            dialog.dismiss();
       }
    });
    

    And call notifyDatasetChanged() when really deleting the item:

    public void deletePullItem(PullSheet sheet, PullItem item)
    {
        sheet.removeItem(item);
        itemAdapter.notifyDatasetChanged();
    }