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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: