Explanation of the getView() method of an ArrayAdapter

Mridang Agarwalla picture Mridang Agarwalla · Sep 13, 2012 · Viewed 12.8k times · Source

Could you explain the getView() method of an ArrayAdapter.

I read the docs and it has three parameters:

  • position: The position of the item within the adapter's data set of the item whose view we want.
  • convertView: The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view.
    Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).
  • parent: The parent that this view will eventually be attached to

I understood the position parameter. Like they said, it's imply the position of the item, who view has been requested.

Where does convertView come from. I've seen many examples where they check if convertView is null. If is is null, they inflate a new instance of the row layout, populate it and return it. I guess I've gotten my head around that too but one thing still baffles me. What is the layout that is passed in through the convertView parameter. Is if the resource parameter that is passed in when initialising the ArrayAdapter? Is is a cached copy of the last layout returned by getView()?

And lastly. What does the parent parameter do. I haven't seen too many examples utilising this. Most of them simply reuse/inflate a row layout and return it.

(I'm asking because I have an on-click animation in my ListView. Specifically this one that aims to replicate Spotify's dropdown quick action menu. My animation has been a little sluggish. After diagnosing this issue for a while, I've realized that this has been due to the fact that my getView() method takes a bit of time to complete as I'm inflating a fresh row layout in every iteration. Someone suggested caching the row layout in a ViewHolder while other examples point to reusing the convertView parameter i.e. only inflating a row layout if convertView is null.)

Answer

user picture user · Sep 13, 2012

Is is a cached copy of the last layout returned by getView()?

The convertView is the view of a row that left the screen(so it isn't the last view returned by the getView method). For example, the list is first shown, in this case convertView is null, no row view was previously built and left the screen. If you scroll down, row 0 will leave the screen(will not be visible anymore), when that happens the ListView may choose to keep that view in a cache to later use it(this makes sense, as the rows of a ListView generally have the same layout with only the data being different). The reason to keep some views in a cache and later use them is because the getView method could be called a lot of times(each time the user scrolls up/down and new rows appear on the screen). If each time the row view would need to be recreated this would have resulted in a lot of objects being created which is something to avoid. In your getView method you would check convertView to see if it is null. If it's null then you must build a new row view and populate it with data, if it isn't null, the ListView has offered you a previous view. Having this previous view means you don't need to build a new row layout, instead you must populate it with the correct data, as that cached view has the old data still attached to it(you would see a lot of questions on stackoverflow where users ask why the rows of their ListView are duplicating when they scroll down).

What does the parent parameter do. I haven't seen too many examples utilising this. Most of them simply reuse/inflate a row layout and return it.

It should be used to get the correct LayoutParams for the newly inflated/built row. For example, if you inflate a layout which has a RelativeLayout as the root and you don't use the parent to get the LayoutParams you could have some problems with the row layout. To take the parent in consideration you would use :

convertView = getLayoutInflater().inflate(R.layout.row_layout, parent, false);