How can I get the current Android view when it displays data that has been updated, and force it to be redrawn? I worked through Android's Notepad tutorial and completed lesson three without any problems — the solution is provided, after all — but I'm stuck on my first non-trivial modification.
I added a new button to the menu, next to the Add note button. When pressed, that button adds a letter to the title of each note in the system. However, the new titles don't show up in the list of notes no matter how long I wait. I know the updater works because the changes do appear if I dismiss the app and bring it back up.
So far, I've discovered that I have to use some kind of invalidation method to make the program redraw itself with the new values. I know that invalidate()
is used from the UI thread and postInvalidate()
is used from non-UI threads 1, 2, but I don't even know which thread I'm in. Also, both of those methods have to be called from the View
object that needs drawing, and I don't know how to obtain that object. Everything I try returns null
.
My main class:
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case INSERT_ID:
createNote();
return true;
case NEW_BUTTON:
expandTitles();
return true;
default:
// Intentionally empty
}
return super.onMenuItemSelected(featureId, item);
}
private void expandTitles() {
View noteListView = null;
// noteListView = findViewById(R.layout.notes_list); // null
// noteListView =
// getWindow().getDecorView().findViewById(android.R.id.content);
// From SO question 4486034
noteListView = findViewById(R.id.body); // Fails
mDbHelper.expandNoteTitles(noteListView);
}
My DAO class:
public void expandNoteTitles(View noteListView) {
Cursor notes = fetchAllNotes();
for(int i = 1; i <= notes.getCount(); i++) {
expandNoteTitle(i);
}
// NPE here when attempt to redraw is not commented out
noteListView.invalidate(); // Analogous to AWT's repaint(). Not working.
// noteListView.postInvalidate(); // Like repaint(). Not working.
}
public void expandNoteTitle(int i) {
Cursor note = fetchNote(i);
long rowId =
note.getLong(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_ROWID));
String title =
note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)) + "W";
String body =
note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY));
updateNote(rowId, title, body);
}
What do I have to do to get the updated note titles to show up as soon as I press the button?
Obviously, I'm a complete newbie to Android. I point this out to encourage you to use small words and explain even obvious things. I know this is the millionth "Android not redrawing" question, but I've read dozens of existing posts and they either don't apply or don't make sense to me.
1: What does postInvalidate() do?
2: What is the difference between Android's invalidate() and postInvalidate() methods?