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.
Either btn_logbook_date
or btn_logbook_date.getText()
is null
.
As shown above, my fillData()
method was being called in my activity's onCreate
, but I was incorrectly calling it BEFORE setting the date on my button. The fillData()
is used to populate the list and initialise my loader. The loader was filtering based on the date displayed on my button. By setting the date on the button AFTER attempting to call fillData()
, the list had no value to get from the button resulting in a NullPointerException.
The correct code is shown again below for clarification purposes.
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);
// Set the text on this button BEFORE calling the fillData() method
btn_logbook_date.setText(strDate);
fillData();
}
private void fillData() {
String[] from = new String[] { AddDBHelper.KEY_BGL, AddDBHelper.KEY_ROWID,
AddDBHelper.KEY_CATEG, AddDBHelper.KEY_TIME };
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) {
// data is not available anymore; delete reference
adapter.swapCursor(null);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With