0

Iam trying to implement a Custom ListView and I have been following the suggestions in this SO question ListView with Add and Delete Buttons in each Row in android. But I am still doing something wrong because when I click the add button in the screen shot below ...

enter image description here ... I catch an error out put this message :

onClick() adapter is NULL!!!

Here is my code:

public class MyActivity extends ListActivity implements OnClickListener {

... 


    @Override
    protected void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);
        setContentView(R.layout.bookmarks);

        addButton = (Button) findViewById(R.id.add_button);
        addButton.setOnClickListener(this);

        bookmarkNameEditText = (EditText) findViewById(R.id.editText);
        Intent i = getIntent();
        default_bookmark_name   = i.getStringExtra("default_bookmark_name");
        currentTrack            = i.getIntExtra("currentTrack",0);
        currentTrackPosition    = i.getIntExtra("currentTrackPosition", 0);
        bookmarkNameEditText.setText(default_bookmark_name);

        datasource = new BookmarkDataSource(this);
        datasource.open();

        ArrayList<Bookmark> values = datasource.getAllBookmarks();
        //instantiate custom adapter
        MyCustomAdapter adapter = new MyCustomAdapter(values, this);

        //handle listview and assign adapter
        ListView lView = (ListView)findViewById(android.R.id.list);
        lView.setAdapter(adapter);
    }


@Override
public void onClick(View src) {
    ArrayAdapter<Bookmark> adapter = (ArrayAdapter<Bookmark>) getListAdapter();
    if (adapter == null ) {
        Log.i(TAG, "MyActivity onClick() adapter is NULL!!!");
        return;
    }

    switch (src.getId()) {
        case R.id.add_button:
            Log.i(TAG, "ADD BUTTON CLICKED");
            String new_bookmark_name = bookmarkNameEditText.getText().toString();
            Log.i(TAG, "MyActivity onClick() new_bookmark_name = [" + new_bookmark_name + "] currentTrackPosition = [" + currentTrackPosition + "]");
            Bookmark bm = datasource.createBookmark(new_bookmark_name, currentTrack,currentTrackPosition);
            //adapter.add(bm);
            Log.i(TAG,"MyActivity onClick() createdBookmark with name = " + bm.getName());
            adapter.add(bm);
            adapter.notifyDataSetChanged();
            break;
    } // end switch
} // end onClick()
Community
  • 1
  • 1
Red Cricket
  • 9,762
  • 21
  • 81
  • 166
  • I would say you have to call `ListActivity#setListAdapter` in `onCreate`, see https://developer.android.com/reference/android/app/ListActivity.html –  Jul 06 '16 at 06:07

2 Answers2

1

The way you should be setting your adapter is, in your onCreate():

setListAdapter(adapter);

For more info on working with ListActivity, see https://developer.android.com/reference/android/app/ListActivity.html

Joel Min
  • 3,387
  • 3
  • 19
  • 38
  • Tried that. I got this runtime error message "MyCustomAdapter cannot be cast to android.widget.ArrayAdapter" when I try to execute:" ArrayAdapter adapter = (ArrayAdapter) getListAdapter();" – Red Cricket Jul 06 '16 at 06:20
  • Yes, exactly what i thought. Your custom adapter probably does not extend ArrayAdapter. Also if you want to add anything to a listview, never add it to the adapter itself, add it to the ArrayList held inside the adapter – Kushan Jul 06 '16 at 06:24
  • if you want your cast to work out, you need your CustomAdapter to extend ArrayAdapter. Or you can do: CustomAdapter localadapter= (CustomAdapter)getListAdapter() – Kushan Jul 06 '16 at 06:26
1

If you want to add to the ListView, you don't need to get the adapter. You need to add to the List the adapter is holding.

Do this:

Declare your values ArrayList as a class member:

 public class MyActivity extends ListActivity implements OnClickListener {
 ArrayList<Bookmark> values 

Then in your onClick:

Directly add to this values ArrayList:

values.add(bm)

and notifyDataSetChanged() below it as you have done. Should work out fine.

Full code:

public class MyActivity extends ListActivity implements OnClickListener {
ArrayList<Bookmark> values
... 


@Override
protected void onCreate(Bundle savedInstanceState) {


    super.onCreate(savedInstanceState);
    setContentView(R.layout.bookmarks);

    addButton = (Button) findViewById(R.id.add_button);
    addButton.setOnClickListener(this);

    bookmarkNameEditText = (EditText) findViewById(R.id.editText);
    Intent i = getIntent();
    default_bookmark_name   = i.getStringExtra("default_bookmark_name");
    currentTrack            = i.getIntExtra("currentTrack",0);
    currentTrackPosition    = i.getIntExtra("currentTrackPosition", 0);
    bookmarkNameEditText.setText(default_bookmark_name);

    datasource = new BookmarkDataSource(this);
    datasource.open();

    values = datasource.getAllBookmarks();
    //instantiate custom adapter
    MyCustomAdapter adapter = new MyCustomAdapter(values, this);

    //handle listview and assign adapter
    ListView lView = (ListView)findViewById(android.R.id.list);
    lView.setAdapter(adapter);
}


@Override
public void onClick(View src) {


switch (src.getId()) {
    case R.id.add_button:
        Log.i(TAG, "ADD BUTTON CLICKED");
        String new_bookmark_name = bookmarkNameEditText.getText().toString();
        Log.i(TAG, "MyActivity onClick() new_bookmark_name = [" + new_bookmark_name + "] currentTrackPosition = [" + currentTrackPosition + "]");
        Bookmark bm = datasource.createBookmark(new_bookmark_name, currentTrack,currentTrackPosition);
        //adapter.add(bm);
        Log.i(TAG,"MyActivity onClick() createdBookmark with name = " + bm.getName());
        values.add(bm);
        adapter.notifyDataSetChanged();
        break;
} // end switch
} // end onClick()
Kushan
  • 5,855
  • 3
  • 31
  • 45
  • Is adapter.notifyDataSetChanged(); a typo in your onClick() method? – Red Cricket Jul 06 '16 at 06:30
  • No, It's the method inside ArrayAdapter. – Kushan Jul 06 '16 at 06:34
  • if you are still getting errors please also share your Adapter code so that i can exactly pinpoint what issue you are facing :) – Kushan Jul 06 '16 at 06:35
  • Thanks Kushan. So is adapter global to the class now? I just don't see where the adapter object gets declared. – Red Cricket Jul 06 '16 at 06:40
  • Honestly changing the values ArrayList or an adapter to members don't really matter. I feel its just good practice to put them as members. Your current declarations are fine. Just that you were trying to cast improperly and add to the adpater(which is not a list) :) anyway hope this solved your issues. Mark as answered if it solves your question – Kushan Jul 06 '16 at 06:44
  • Thanks Kushan, This lead me to a solution. – Red Cricket Jul 06 '16 at 06:52