-1

I am getting the following error while trying to delete specific entry from listview and hashmap:

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
                  at java.util.ArrayList.get(ArrayList.java:411)
                  at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:349)
                  at android.widget.AdapterView.getItemAtPosition(AdapterView.java:790)
                  at com.example.cmmalli.helloworld.MainActivity.onContextItemSelected(MainActivity.java:120)
                  at android.app.Activity.onMenuItemSelected(Activity.java:3224)
                  at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:406)
                  at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
                  at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:103)
                  at com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback.onMenuItemSelected(PhoneWindow.java:3722)
                  at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:761)
                  at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
                  at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:904)
                  at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:894)
                  at com.android.internal.view.menu.MenuPopup.onItemClick(MenuPopup.java:128)
                  at android.widget.AdapterView.performItemClick(AdapterView.java:310)
                  at android.widget.AbsListView.performItemClick(AbsListView.java:1155)
                  at android.widget.AbsListView$PerformClick.run(AbsListView.java:3126)
                  at android.widget.AbsListView$3.run(AbsListView.java:4041)
                  at android.os.Handler.handleCallback(Handler.java:751)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

My Code is:

public class MainActivity extends AppCompatActivity {

ArrayAdapter adapter;
TextView user_name;
TextView user_amount;
ImageButton addbtn;
ListView listView;
HashMap<String, Double> myMap = new HashMap<String, Double>();

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

    user_name = (TextView) findViewById(R.id.nameeditText);
    user_amount = (TextView) findViewById(R.id.amounteditText);
    addbtn = (ImageButton)findViewById(R.id.moreImageButton);
    listView = (ListView)findViewById(R.id.simple_list_item_1);
    registerForContextMenu(listView);

    adapter = new ArrayAdapter<User>(
            MainActivity.this,
            android.R.layout.simple_list_item_1);

    listView.setAdapter(adapter);

    addbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String name = user_name.getText().toString();
            Double amount = Double.parseDouble(user_amount.getText().toString());
            adapter.add(new User(name, amount));
            adapter.notifyDataSetChanged();
            myMap.put(name,amount);

            Iterator myVeryOwnIterator = myMap.keySet().iterator();
            while(myVeryOwnIterator.hasNext()) {
                Toast.makeText(getBaseContext(), (String) myVeryOwnIterator.next(),
                        Toast.LENGTH_SHORT).show();
            }

        }
    });



}


@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderTitle("Options");
    if (v.getId()==R.id.simple_list_item_1) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_list, menu);
    }
}


@Override
public boolean onContextItemSelected(MenuItem item) {
    android.widget.AdapterView.AdapterContextMenuInfo info = (android.widget.AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    switch(item.getItemId()) {
        case R.id.edit:
            //edit name or amount here
            return true;
        case R.id.delete:
            adapter.remove(listView.getItemAtPosition(info.position));
            adapter.notifyDataSetChanged();
            myMap.remove(listView.getItemAtPosition(info.position));
            return true;
        case R.id.deleteall:
            adapter.clear();
            adapter.notifyDataSetChanged();
            myMap.clear();
            return true;
        default:
            return super.onContextItemSelected(item);
    }
}


public class User {
    public String name;
    public double amount;

    public User(String name, double amount) {
        this.name = name;
        this.amount = amount;
    }

    @Override
    public String toString() {
        return format("%s : %.2f", this.name, this.amount);
    }
}

On long click over a row in listview, it gives options of edit, delete and delete all. Delete all option works, but delete option for specific row gives error. I am not sure where am I going wrong. Suggestions would be much appreciated. I am trying to take User_name and amount from user and then show it in the listview and store the key value pair in a hashmap so that it can be edited as well.

charsi
  • 399
  • 1
  • 5
  • 13
  • I am trying to use HashMapAdapter a custom adapter which extends base adapter for this but not sure how to set and get values through it. Also not sure how to set the HashMapadapter to listview and how to set and get values from it. it would be great if someone can put a little light on that for me as well. Using the following custom adapter example [http://stackoverflow.com/questions/5234576/what-adapter-shall-i-use-to-use-hashmap-in-a-listview/40531313#40531313] – charsi Nov 10 '16 at 19:03
  • Your adapter is empty, apparently. How are you able to select any item to delete it? – OneCricketeer Nov 11 '16 at 21:40

1 Answers1

0

Your error is that the Adapter is empty, so you'll need to add some data to it before you can start deleting things from it.

I am not sure why you need the HashMap, but if you are wanting to remove an element from the adapter, you'll probably need an ArrayList.

(I renamed the ListView ID because it is not a simple list item)

public class MainActivity extends AppCompatActivity {

    ArrayAdapter<User> adapter;
    List<User> users;   // added
    ListView listView;

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

        listView = (ListView)findViewById(R.id.listView);
        registerForContextMenu(listView);

        users = new ArrayList<User>();   // added

        adapter = new ArrayAdapter<User>(
                MainActivity.this,
                android.R.layout.simple_list_item_1
                users);   // added

        listView.setAdapter(adapter);
        // listView.setOnLongClickListener...  // You also could use this...

I don't have much experience with context menus, but I am imagining something like this

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderTitle("Options");
    if (v.getId()==R.id.listView) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_list, menu);
    }
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    final int index = info.position;
    final User u = users.get(index);  // or adapter.getItem(index);

    switch(item.getItemId()) {
        case R.id.edit:
            //edit name or amount here
            return true;
        case R.id.delete:
            users.remove(index);
            adapter.notifyDataSetChanged();
            return true;
        case R.id.deleteall:
            users.clear();
            adapter.notifyDataSetChanged();
            return true;
        default:
            return super.onContextItemSelected(item);
    }
}
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I need hashmap to create key value pairs of users and their respective amounts, so that they can be editted and I can do maths on the amounts of the individual users. ArrayList wont let me keep key value pairs. – charsi Nov 11 '16 at 21:57
  • Your `User` objects can be modified directly. `sampleUser.name = "new Name"`. And notify the adapter, and the data should update – OneCricketeer Nov 11 '16 at 21:58