1

Currently I am making an app in Android which is a todo list, it has a edit text, button and a listview, when button is clicked the text is added to listview, everything works fine but when i add too many items to list view and try to select a list item my app stops working and I get a error saying java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference Does anyone know a fix? this is my view data method whcih displays items in listview

public void viewdata(String tablename)
{
    db = new mydbhandler(this);
    lvitemslist = findViewById(R.id.lvitemlist);
    ArrayList mylist = new ArrayList();
    Cursor c = db.getdata(tablename);
    while(c.moveToNext())
    {
        mylist.add(c.getString(1));
    }
    ListAdapter mylistadapter = new ArrayAdapter(this,R.layout.custom_item_row,R.id.ctv,mylist);
    lvitemslist.setAdapter(mylistadapter);


}

and this is the onitemclicklistener

lvitemslist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            View v = lvitemslist.getChildAt(i);
            CheckedTextView ctv = v.findViewById(R.id.ctv);

                ctv.setCheckMarkDrawable(android.R.drawable.checkbox_on_background);

db.deletedata(tablename,ctv.getText().toString());

viewdata(tablename);

  • 2
    I can only suggest changes to something I can see, so my advice is: share enough code so we can reproduce the problem. Or if you still hesitate because it *does* take some time to write a good question, maybe read [this post](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) on how to analyse and fix NullPointerExceptions – Bö macht Blau Aug 21 '18 at 18:10
  • 1
    yes i have edited my question with the code thanks for replying. my problem is that it works for small list ..but when the items for more than 10 or so the app crashes – Omkar Nadkarni Aug 22 '18 at 15:27

1 Answers1

0

Take a look at this line from your OnItemClickListener:

View v = lvitemslist.getChildAt(i);

I guess you want to assign the ListView row which was clicked to the variable v. But the ViewGroup method getChildAt(int) (ListView is a kind of ViewGroup) will give you

the view at the specified position or null if the position does not exist within the group

(quoted from the ViewGroup documentation)

Like you said, this works for the first few items but for higher positions the app crashes. This is because the ListView has a fixed number of child Views: about as many as fit on the screen simultaneously plus some more to enable smooth scrolling. For every clicked row beyond that fixed number, lvitemslist.getChildAt(i) will return null.

What can you do to fix your code?

Luckily you do not have to do much work to get the clicked View, it is handed to you as one of the parameters of onItemClick(): the second parameter is the clicked ListView row.

So you just need to write

lvitemslist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) {
        CheckedTextView ctv = view.findViewById(R.id.ctv);
        ctv.setCheckMarkDrawable(android.R.drawable.checkbox_on_background);
        db.deletedata(tablename,ctv.getText().toString());
        viewdata(tablename);
    }
}

This will help you to avoid the NullPointerException.

Another thing: you change the appearance of a ListView row from outside of the Adapter by calling

ctv.setCheckMarkDrawable(android.R.drawable.checkbox_on_background);

This is dangerous (there are lots of questions on this site where people had weird behaviour when scrolling as a consequence). It may not be a problem in your case because you refresh the whole ListView soon afterwards. But generally one should provide the Adapter with all the data necessary to decide what each row should look like. Then one can change the data list and after that of course call notifyDatasetChanged() on the Adapter.

Bö macht Blau
  • 12,820
  • 5
  • 40
  • 61
  • i cannot thank you enough..that worked like a charm ..thanks alot... although i didnt understand the last part but i think what youre trying to say is using a custom adapter and changing the drawable from there – Omkar Nadkarni Aug 23 '18 at 18:42
  • @Omkar Nadkarni - you're welcome :) And yes, I was trying to say you should use a custom Adapter for changing the drawables. Please accept this answer (click grey checkmark) since it was helpful for you – Bö macht Blau Aug 23 '18 at 18:58