25

I have a custom CursorAdaptor in my project with overridden methods bindView(View view, Context context, Cursor cursor) and newView(View view, Context context, Cursor cursor). I want to know for what CursorAdapter are used for and what is the difference between and uses of overriding bindView() and newView().

I have read the Developer Site and this tutorial but still I didn't understood. As I'm a beginner to Android, please help me understand this concept.

Jainendra
  • 24,713
  • 30
  • 122
  • 169
  • http://stackoverflow.com/a/12224738/995891 one is for creating a new re-usable layout, the other for binding the cursor data to that view – zapl Oct 01 '12 at 12:02
  • 1
    The basic premise of a CursorAdapter is to manage a cursor object from the database. Here is a quote from docs: "Adapter that exposes data from a Cursor to a ListView widget." – IgorGanapolsky Jul 29 '14 at 13:33

1 Answers1

126

In order to understand this, you must first understand how BaseAdapter works, since CursorAdapter is a subclass of BaseAdapter.

Android maintains a pool of views for a ListView which it will give to you so you can reuse it instead of creating a new view each time.

In BaseAdapter, you will have a function called getView(), to which one of the parameters is a View object named convertView. Basically, this convertView will be null if the list is being loaded for the first time, and it will not be null once you start sliding the list. Therefore, in the getView() method of your BaseAdapter, you will check if convertView is null. If yes, you will inflate it. Then you can use the view and set its elements as normal. This will improve the scrolling performance of a listview tremendously.

A CursorAdapter makes it easy to use when the data source of a listview is a database. In a cursor adapter, however, Android takes care of checking whether the convertView is null or not. In the newView() method, you simply inflate the view and return it. In the bindView() method, you set the elements of your view.

As an example, imagine a listview on a device which can show upto 11 list items on the screen. In this case, newView() will be called upto 11 times. However, bindView() will be called many times whenever you scroll the list view. The 11 views you created in your newView method will be reused again and again as you scroll the list.

Ped7g
  • 16,236
  • 3
  • 26
  • 63
Vinay S Shenoy
  • 4,028
  • 3
  • 31
  • 36
  • 6
    What about the ViewHolder pattern? Is there still use for it today in JB and all the new api's? – Yosi199 Apr 11 '13 at 12:56
  • 6
    `ViewHolder` is now deprecated in favour of using `void setTag(int, object)` and `object getTag(int)` which lets you attach references to any sub-views to the parent view (`setTag(R.id.thing, thingView)`) and then get them back quickly (`getTag(R.id.thing)` would return `thingView`). – Andrew Wyld Apr 11 '13 at 14:10
  • 6
    @AndrewWyld, That's the ViewHolder pattern - http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder – Vinay S Shenoy Apr 11 '13 at 18:13
  • @Yosi199, By `ViewHolder` pattern, I assume you're referring to this - http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder In my personal experience, hardware which runs `Jellybean` won't give you a noticeable difference as long as you reuse the `convertView` properly. However, I still use the `ViewHolder` pattern as I find it allows me to manage the views nicely and abstract away some methods as `Viewholder.getHolderForView(View v)` – Vinay S Shenoy Apr 11 '13 at 18:19
  • @AndrewWyld, My mistake, that isn't the `ViewHolder` pattern. @Yosi199, `ViewHolder` is not exactly deprecated, but it can cause issues pre-ICS if you use it with the `setTag(int key, Object holder)` method because of how indexed tags were implemented pre-ICS. – Vinay S Shenoy Apr 11 '13 at 18:39
  • @VinaySShenoy I'm trying to find the dev blog I read it on, and I can't! Anyway, `setTag(int, object)` and `getTag(int)` does all the same work `ViewHolder` does and I heard it was considered a cleaner method. Or you can make a custom view class :) – Andrew Wyld Apr 12 '13 at 09:32
  • 1
    @AndrewWyld, That particular dev blog had the post removed for some reason.. :-).. Yes, I know it does, but using `ViewHolder` with setTag(int, holder) would cause serious issues in pre-ICS. I still prefer ViewHolder simply because I find the implementation cleaner... I just have to be careful with pre-ICS devices. – Vinay S Shenoy Apr 12 '13 at 10:17
  • @VinaySShenoy just to be clear, though, I'm not typically using `ViewHolder`, just the tags ... does that cause issues? – Andrew Wyld Apr 15 '13 at 12:25
  • 1
    On Pre-ICS devices, if you use `setTag(int, tag)` where `tag` holds a reference to a `View`, then you'll end up leaking the entire view and its context(most likely, an Activity). Otherwise, you're safe. – Vinay S Shenoy Apr 15 '13 at 16:15
  • Thank you guys very much for all this info. I'm gonna use the ViewHolder pattern for my current app since it's JB only buy I would really appreciate if you could show me how it's done without the ViewHolder? – Yosi199 Apr 20 '13 at 07:03
  • Really helpful for freshers of android, Help me for this: http://stackoverflow.com/questions/19196322/edittext-in-gridview-how-to-get-value-from-edittext – Pratik Butani Oct 07 '13 at 04:57
  • @VinaySShenoy as you said "On Pre-ICS devices, if you use setTag(int, tag) where tag holds a reference to a View, then you'll end up leaking the entire view and its context(most likely, an Activity). Otherwise, you're safe. –" then how to reuse views pre-ics with view holder or with without holder it would be same case...not getting exactly – Akhil Dad Jan 29 '14 at 06:16
  • @AkhilDad Not quite. On pre-ICS devices, you'll use the `setTag()` method which doesn't cause the leak. The leak is caused if you use the `setTag(int, int)` method only. – Vinay S Shenoy Jan 29 '14 at 09:43
  • @VinaySShenoy setTag(int,Object) if that object is view only or itcan be anything say a String would cause problem and moreover setTag() we can use view or it is ViewHolder class that contain views. and I would love to know if you can paste some code in which you have done both the things according to android version or you made separate adapters? – Akhil Dad Jan 29 '14 at 12:24
  • 1
    `setTag(int, Object)` will still cause leaks, but if it's not a View instance, there won't be too much of a problem. It's only when the tag has a reference to a `Context` that will cause issues as it will end up leaking the `Activity`. – Vinay S Shenoy Jan 29 '14 at 15:11
  • However, in `setTag()`, if you want to retain just a single reference to a View, you can use the `View` as the tag directly. Otherwise, write a `ViewHolder` class to encapsulate the `View` references you need. – Vinay S Shenoy Jan 29 '14 at 15:12
  • @VinaySShenoy Thanks :) Can you tell me more about how you find that view will cause leaking of an activity and also does tag makes any effects on list view scroll – Akhil Dad Feb 07 '14 at 08:01
  • 1
    And no, tag by itself shouldn't be having an effect on listview scroll. What has an effect is what you do in getView()/bindView() – Vinay S Shenoy Feb 07 '14 at 09:44
  • I have created getView() only and Its working: how it is possible, Can you explain.?? Link is here: http://pastebin.com/W9FBG7Wt – Pratik Butani Feb 15 '14 at 11:04
  • CursorAdapter is a subclass of baseAdapter, and thus, it implements getView() on it's own. You have just overriden that method, and hence, it will work. – Vinay S Shenoy Feb 17 '14 at 05:09
  • @VinaySShenoy What to do if i have to use `ViewHolder` and `SubViewHolder`, Once i have inflate layout from `newView` but what about their child layout? – Pratik Butani Nov 27 '14 at 08:10