What bindView() and newView() do in CursorAdapter
Asked Answered
F

1

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.

Forequarter answered 1/10, 2012 at 11:53 Comment(2)
https://mcmap.net/q/537665/-cursoradapter-bindview-optimization one is for creating a new re-usable layout, the other for binding the cursor data to that viewAwildaawkward
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."Lurlenelurline
S
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.

Sonneteer answered 1/10, 2012 at 12:10 Comment(21)
What about the ViewHolder pattern? Is there still use for it today in JB and all the new api's?Protestation
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).Odrick
@AndrewWyld, That's the ViewHolder pattern - developer.android.com/training/improving-layouts/…Sonneteer
@Yosi199, By ViewHolder pattern, I assume you're referring to this - developer.android.com/training/improving-layouts/… 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)Sonneteer
@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.Sonneteer
@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 :)Odrick
@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.Sonneteer
@VinaySShenoy just to be clear, though, I'm not typically using ViewHolder, just the tags ... does that cause issues?Odrick
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.Sonneteer
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?Protestation
Really helpful for freshers of android, Help me for this: #19196822Trieste
@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 exactlyKissel
@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.Sonneteer
@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?Kissel
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.Sonneteer
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.Sonneteer
@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 scrollKissel
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()Sonneteer
I have created getView() only and Its working: how it is possible, Can you explain.?? Link is here: pastebin.com/W9FBG7WtTrieste
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.Sonneteer
@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?Trieste

© 2022 - 2024 — McMap. All rights reserved.