RTFM

Going back to re-scan the Android dev guide now that I understand a bit better what’s going on. It makes a lot more sense now.

First I had a look at binding list views to data. This bit of code had some nuggets:

ArrayAdapter adapter = ArrayAdapter.createFromResource(
   
this, R.array.colors, android.R.layout.simple_spinner_item);
adapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

My code was similar, except the setDropDownViewResource call was commented out because the method was unavailable when I tried it; looking more closely I saw that I’d set adapter to type SpinnerAdapter – which is just an interface without the actual methods of an actual Adapter; wonder where I got that from? Correct typing allowed me to use the method. I had not noticed before that there were prefab views available for the spinner; oddly, however, using these resulted in invisible text and strange buttons on the dropdown:

(And, just now noticing that ScribeFire isn’t inserting an image intuitively. Bleh. Not that WordPress hasn’t given me “shaking fist syndrome” from trying to insert images too.)

Also discovered notifyDataSetChanged() which keeps me from having to create a new cursor and adapter when I know or suspect the data for the view has changed. I guess that’s one of the benefits of Activity cursor management? Just requires retrieval and careful casting of the adapter to call the method. Going to try it now. In my case, with a custom adapter (subclassing SimpleCursorAdapter), it looks like so for my ListActivity:
    ((EventCursorAdapter) getListAdapter()).notifyDataSetChanged();
Well, that does not in fact re-run the query and get the new data. So that’s a bit misleading. But it DOES seem to work for my spinner:
    ((SimpleCursorAdapter) mSpinner.getAdapter()).notifyDataSetChanged();
Hmm… what’s the difference? Stack Overflow has someone recommending futzing with the cursor directly on the ListActivity though the next response indicates notifyDataSetChanged should work. Comments on this ListActivity tutorial indicate some puzzlement about the issue as well. A response here indicates it should work.

It looks like SimpleCursorAdapter gets its notifyDataSetChanged method from BaseAdapter, which probably does nothing but update the view as no query logic could be involved. That doesn’t explain why there’s different behavior between a Spinner and ListActivity which both use SimpeCursorAdapters, but it suggests I can try overriding the method in my custom adapter and requerying the cursor.
    @Override
    public void notifyDataSetChanged() {
        getCursor().requery();
        super.notifyDataSetChanged();
    }

Ooh! Bad idea! Apparently the requery causes notifyDataSetChanged to be called and it recurses into a stack overflow. I can add a separate method to try the same thing, though. And… that works – and the cursor requery automatically kicks off the notify and redraw.

I must be missing something. I don’t understand why I’d need to explicitly requery in the case of an adapter for ListActivity and only need to notify for a Spinner.

Advertisements