Filtering ListView by 'selection' parameter in CursorLoader

Ronnie picture Ronnie · Oct 21, 2012 · Viewed 9.6k times · Source

I either have my syntax incorrect or I haven't understood how Loaders work yet, but I've currently got a ListView showing all items in my database. The activity has a button with today's date showing. The user can click this to bring up a Date Dialog or can press the Prev/Next buttons to change the date displayed. I'd like to filter the ListView based on the date showing, so only records with that date saved in will display.

Currently all records are showing with

public Loader<Cursor> onCreateLoader(int id, Bundle args) {         
    CursorLoader cl = new CursorLoader(this, DBProvider.CONTENT_URI,
            null, null, null, null);
    return cl;
}

I've tried a few variations based on what I'm seeing online but essentially I'm trying to include a 'selection' that shows today's date as a string (it's already been through SimpleDateFormatter and set as the text on the button).

public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    String[] selectDate = { btn_logbook_date.getText().toString() };
    CursorLoader cl = new CursorLoader(this, DBProvider.CONTENT_URI,
            null, "Date=?", selectDate , null);
    return cl;
}

and

public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    String selectDate = btn_logbook_date.getText().toString();
    String selection = "(" + AddDBHelper.KEY_DATE + "=" + selectDate + ")";

    CursorLoader cl = new CursorLoader(this, DBProvider.CONTENT_URI,
            null, selection, null, null);
    return cl;
}

both generate NullPointerExceptions. Any pointers on the correct method to filter this on creating the loader would be appreciated.

UPDATE

It seems the NullPointerException was occurring because I was calling the fillData() method (used to populate my ListView) before calling my btn_logbook_date.setText() method. I've moved this further down in my activity's onCreate and the application no longer crashes, but the data is not populating anymore. I realised that if I save a new record in with today's date, it shows up in my listview, but when changing days no other records are appearing. Changing back to today in the ListView activity also shows up blank.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView (R.layout.dash_logbook);     
    this.getListView().setDividerHeight(2);         

    ListView list = getListView();
    list.setOnItemClickListener(this);

    btn_logbook_date = (Button) findViewById(R.id.btn_logbook_date);
    now = Calendar.getInstance();
    nowD = now.getTime();

    SimpleDateFormat dFormatter = new SimpleDateFormat("dd MMM yyyy");
    strDate = dFormatter.format(nowD);
    btn_logbook_date.setText(strDate);              

    fillData();
}

// I have code here to call on the DateDialogFragment

public void updateDatePrev() {
    String prevVar[] = btn_logbook_date.getText().toString().split(" ");

    if (prevVar[1].equalsIgnoreCase("Jan")) {
        lMonth = 0;
    } else if (prevVar[1].equalsIgnoreCase("Feb")) {
        lMonth = 1;
    } else if (prevVar[1].equalsIgnoreCase("Mar")) {
        lMonth = 2;
    } else if (prevVar[1].equalsIgnoreCase("Apr")) {
        lMonth = 3;
    } else if (prevVar[1].equalsIgnoreCase("May")) {
        lMonth = 4;
    } else if (prevVar[1].equalsIgnoreCase("Jun")) {
        lMonth = 5;
    } else if (prevVar[1].equalsIgnoreCase("Jul")) {
        lMonth = 6;
    } else if (prevVar[1].equalsIgnoreCase("Aug")) {
        lMonth = 7;
    } else if (prevVar[1].equalsIgnoreCase("Sep")) {
        lMonth = 8;
    } else if (prevVar[1].equalsIgnoreCase("Oct")) {
        lMonth = 9;
    } else if (prevVar[1].equalsIgnoreCase("Nov")) {
        lMonth = 10;
    } else if (prevVar[1].equalsIgnoreCase("Dec")) {
        lMonth = 11;
    }

    int lYear = Integer.parseInt(prevVar[2]);
    int lDay = Integer.parseInt(prevVar[0]);
    now = Calendar.getInstance();
    now.set(Calendar.YEAR, lYear);
    now.set(Calendar.MONTH, lMonth);
    now.set(Calendar.DAY_OF_MONTH, lDay - 1);
    PrevDate = now.getTime();
    SimpleDateFormat prevDFormatter = new SimpleDateFormat("dd MMM yyyy");
    strDate = prevDFormatter.format(PrevDate);
    btn_logbook_date.setText(strDate);      
}

public void updateDateNext() {
//same code as above, except adding +1 to the days when clicked
}

private void fillData() {
    // Fields from the database (projection) must include
    // the _id column for the adapter to work
    String[] from = new String[] { AddDBHelper.KEY_BGL, AddDBHelper.KEY_ROWID,
            AddDBHelper.KEY_CATEG, AddDBHelper.KEY_TIME };
    // Fields on the UI to which we map
    int[] to = new int[] {R.id.logBGL, R.id.logRowID, R.id.logCateg, R.id.logTime };

    getLoaderManager().initLoader(0, null, this);
    adapter = new SimpleCursorAdapter(this, R.layout.logbook_item, null, from, to, 0);

    setListAdapter(adapter);        
}    

public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     String selection = AddDBHelper.KEY_DATE + "=?";
     String[] selectionArgs = { String.valueOf(btn_logbook_date.getText().toString()) };

    CursorLoader cl = new CursorLoader(this, DBProvider.CONTENT_URI,
            null, selection, selectionArgs, null);
    return cl;
}

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    adapter.swapCursor(data);
}

public void onLoaderReset(Loader<Cursor> loader) {
    adapter.swapCursor(null);
}

When originally saving to the database from a different activity, I'm also using the SimpleDateFormat method and converting to the same format as above, so the saved strings and the Text being displayed on the button should match.

UPDATE

I've answered this question below. The issue about repopulating the list will be asked separately as the original question was only regarding filtering the list by date. I confirmed this was working by creating new records with today's date and having them populate when opening the listview activity. By changing the date in the Android emulator and then re-opening the application and listview activity, i could see the records belonging to the newly set date.

Answer

CL. picture CL. · Oct 21, 2012

Either btn_logbook_date or btn_logbook_date.getText() is null.