Search code examples
androidlistviewnullpointerexceptionandroid-cursoradapter

Deleting a row from a ListView using Button associated with it


I have a listview on which i am showing data from my database and now i want to delete row on the basis of button clicked which is associated with each row.

i am having exception in CustomAdapter class whenever i press Done button. CursorAdapter code is this:

public class CustomAdapter extends CursorAdapter {
  TextView task,daate;
  Button del;
  public static int id;
  Context ct;
  public CustomAdapter(Context context, Cursor cursor) {
    super(context, cursor, 0);
}

// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    ct=context;
    return LayoutInflater.from(context).inflate(R.layout.adapter, parent, false);

}

// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final DatabaseHelper help=new DatabaseHelper(ct);
    del = (Button) convertView.findViewById(R.id.deleteBtn);
    del.setOnClickListener( new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                  help.deleteRecordWithId(position);
                                }
                            }
    );
    return super.getView(position, convertView, parent);
}


@Override
public void bindView(View view, Context context, final Cursor cursor) {
    // Find fields to populate in inflated template
        task = (TextView) view.findViewById(R.id.dynamicTask);
        daate = (TextView) view.findViewById(R.id.dynamicDate);
        id=cursor.getInt(cursor.getColumnIndex("_id"));
    String Task=cursor.getString(cursor.getColumnIndex("task"));
    String Daate=cursor.getString(cursor.getColumnIndex("ddate"));
    task.setText(Task);
    daate.setText(Daate);
}

}

and my database function deleteRecordWithId() is:

 public boolean deleteRecordWithId(int id) {
    SQLiteDatabase db=this.getWritableDatabase();
    long rows=db.delete(TABLE_NAME,"_id=?",new String[] {String.valueOf(id)});
    if(rows>0) {
        return  true;
    }
    else {
        return false;
    }
}

and i am getting this exception:

  java.lang.NullPointerException: Attempt to invoke virtual method 
  'android.view.View android.view.View.findViewById(int)' on a null object 
  reference

What is wrong in this code. please help me to rectify it.


Solution

  • First Method: You describe like that

    public class CustomAdapter extends CursorAdapter {
    
    TextView task,daate;
    Button del;
    public static int id;
    Context ct;
    public CustomAdapter(Context context, Cursor cursor) {
        super(context, cursor, 0);
    }
    
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        ct=context;
        return LayoutInflater.from(context).inflate(R.layout.adapter, parent, false);
    
    }
    
    @Override
    public void bindView(View view, Context context, final Cursor cursor) {
        // Find fields to populate in inflated template
        task = (TextView) view.findViewById(R.id.dynamicTask);
        daate = (TextView) view.findViewById(R.id.dynamicDate);
        id=cursor.getInt(cursor.getColumnIndex("_id"));
        String Task=cursor.getString(cursor.getColumnIndex("task"));
        String Daate=cursor.getString(cursor.getColumnIndex("ddate"));
        task.setText(Task);
        daate.setText(Daate);
        final DatabaseHelper help=new DatabaseHelper(ct);
        del = (Button) convertView.findViewById(R.id.deleteBtn);
    }}
    

    MainActivity:

    public class MainActivity{
    private CustomAdapter cursorAdapter;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
    
        cursorAdapter = new CustomAdapter(this, null);
    }
    public void deleteRecordWithId(View view) {
        View parentRow = (View) view.getParent().getParent();
        ListView listView = (ListView) view.getParent().getParent().getParent();
        int position = listView.getPositionForView(parentRow);
        long id = cursorAdapter.getItemId(position);
    
        SQLiteDatabase db=this.getWritableDatabase();
    long rows=db.delete(TABLE_NAME,"_id=?",new String[] {String.valueOf(id)});
    if(rows>0) {
        return  true;
    }
    else {
        return false;
    }
    }
    }
    

    and xml like that:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    android:id="@+id/task_outer_container"
                    android:layout_width="match_parent"
                    xmlns:app="http://schemas.android.com/apk/res-auto"
                    android:gravity="center_vertical"
                    android:background="@drawable/background_transparent"
                    android:layout_height="wrap_content"
                    android:clipToPadding="false"
                    android:clipChildren="false"
        >
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerVertical="true"
            android:id="@+id/delete_button"
            android:onClick="deleteRecordWithId"
            app:srcCompat="@drawable/remove_icon"
            android:background="@drawable/background_transparent"
            android:layout_gravity="center_vertical"
            android:adjustViewBounds="false"
            android:paddingStart="7dp"
            android:paddingEnd="7dp"
            android:layout_marginEnd="-5dp"/>
    
    </RelativeLayout>
    

    Second Method: You should not use getView in the Cursoradapter. You need to do all the operations in bindview. So uou can not reach id with getview.

    For example: https://github.com/rodoggx/w4d1_Simple_CursorAdapter/blob/master/app/src/main/java/com/example/sqlitecursoradapter/CustomAdapter.java