Search code examples
androidandroid-imageviewsimplecursoradapterandroid-viewbinder

Lifecycle of calls when using the SimpleCursorAdapter.setViewImage


OK, trying to get images from my SD card to show in an activity ListView.

I'm reading lots of hints, but I'm missing an important chunk. I'd love to see a short-ish bit of source code that illustrates this, haven't found anything yet.

From my research it sounds like bindview() is called when listview.setadapter(SimpleCursorAdapter adapter) is executed. The documentation says that setImageView is called by bindview if the ViewBinder cannot handle an ImageView.

You specify the field in the FROM array, the id of the TextView in the TO array, the Cursor, and the view group with the TextView. Then set the adapter to the ListView and voila, it happens.

I think the call sequence is then: listView.setAdapter(SimpleCursorAdapter adapter)->adapter.bindView()->adapter.setTextView

Bindview must determine the view is of type TextView, determine that it can bind it, passes theTextViewand text value from the cursor andsetTextView` does its thing.

So, that makes the call for an ImageView very similar, right?

listViw.setAdapter(SimpleCursorAdapter adapter)->adapter.bindView()->adapter.setImageView

So when bindView comes across and object of type ImageView, what does it do? Is there a default implementation like in setTextView? I'd imagine it would be hard to do that, images vary so much. Text is text, but images have formats, sizes, depths, scale, LOCATIONS, etc, etc. The string passed to the setTextView IS the text, the payload. In an image the string is (probably) the filename, only the starting point of an image.

I think I'll need to build my adapter with the database column name that holds the filename in FROM. The TO array will have just the id of the ImageView in my layout. I think I can use the default viewbinder bindview(), but will have to override setImageView() to take the expected string (filename), and build out the image loading lines to find that image name in the expected application path.

So that will be (maybe):

listView.setAdapter(MyOwnSimpleCursorAdapter myOwnAdapter)->myOwnAdapter.super.bindView()->myOwnAdapter.setImageView()

Does this sound right? If anyone can fill in the missing gaps and/or provide some working source code it would help a lot. By the way, I've written code to do this, but it isn't working. It could be a very simple bug and don't want to stop this thread if it's do-able. I think I just need a little nudge in the right direction.


Solution

  • I don't quite understand what is your question(and yes, you should post the failing piece of code) so here is my answer(you can also see this in the source code of the SimpleCursorAdapter):

    In a SimpleCursorAdapter when the ListView requires a new View to be shown the method getView() will be called. This methods delegates the row building to 2 methods: newView()(which will create the View(inflating the xml layout you've set) and set as a tag an array of the Views with the ids from the to array) and bindView()(which will actually bind the data to the View created by newView()).

    bindView() will then iterate through the arrays of Views(the Views with the ids from the to array) on which to bind the data. It will also call getString(and only the getString method, this is important) from the cursor to get the data. Next the method checks if a ViewBinder has been set on the adapter, if this is the case it will let that ViewBinder to set the data(the methods setTextView() and setImageView() will not be called if the ViewBinder successfully binds the data).

    If a ViewBinder wasn't set on the adapter or the setViewValue method of the ViewBinder returns false(meaning the ViewBinder has failed) then the bindView() method will check and see which type of View it is dealing with(TextView or ImageView) and call either setViewText() or setViewImage().

    The implementation of the setViewImage() will try to parse the supplied String as an int (example: an image id R.drawable.image) and if this fails it will then parse the String as an Uri and use setImageUri() on the ImageView. So an int like R.drawable.image or a String like "file://mnt/sdcard/photo100.jpg" should work with the default implementation of the SimpleCursorAdapter, otherwise override the setImageView.