List with custom objects and adapter
NewsEntryAdapter
Create a new class that extends ArrayAdapter<NewsEntry>. You’ll need to provide a constructor; we’ve selected the (Context, int) signature for our purposes. Additionally we want to override the getView() method to customize how we’ll build each view.
Here is the final class we built. Don’t worry, we’ll dissect this class to understand everything it’s doing.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
|
The constructor we’ve specified below receives a Context and an int.
We must specify the Context to our parent class, ArrayAdapter, and the newsItemLayoutResource tells us which layout we should use for each news item. We’ve already created one at res/layout/news_entry_list_item.xml, so the resource we’ll pass into this constructor will be R.layout.news_entry_list_item.
getView()
Here we’re overriding the getView() method of ArrayAdapter.
There’s a lot going on here, so let’s break it down. First we’ll talk about the method’s arguments (specifically convertView), the workingView, and then viewHolder.
The primary functionality of the adapter starts at getView. This is what is called each time the ListView needs something to display.
The position argument tells us which item in the array of objects we added is being rendered (which can be very useful to know.)
The convertView argument is our possibly-recycled view. If this is non-null, then this is a view that’s no longer visible and should be used to conserve view objects. If it is null, then we’ll go ahead and create a new view. The resulting view (either reused or newly created) is what we call the working view.
The parent argument is a reference to the parent view containing ours (ListView.) It’s not necessary for our purposes here.
The following lines determine our working view and retrieve a ViewHolder plus the corresponding NewsEntry object.
We’ll take a look at getWorkingView() and getViewHolder() soon enough. The getItem() simply returns to us the NewsEntry we’re currently trying to render for the ListView to display.
The remaining lines perform the actual decoration of the view:
The title is set simply to the NewsEntry title. The subtitle requires a little bit of date formatting, but isn’t altogether hard. Like the title, the image is set simply to the NewsEntryIcon.
Finally we return the view at the end of getView(), which will cause it to be recycled later on when possible.
getWorkingView()
Here we define our own method getWorkingView().
The working view is the result of whether we have a recycled view or forced to create a new one. This should be pretty straightforward.
getViewHolder()
Here we define our own method getViewHolder().
The ViewHolder is a custom class defined out of convenience, efficiency, and some type safety. The primary benefit of the ViewHolder relies on the fact that, when stored as a view’s tag, it is recycled along with the view itself. A view can store any object, known as its tag, for convenient referencing. In our case, we will store an object that already has direct references to the subviews within the item layout. This avoids having to re-lookup (through findViewById()) each subview each time it’s re-drawn. As the number of getView() calls increase, the number of times findViewById() is invoked remains the same at a certain point. We can also cast it to our specific types of views (TextView, ImageView) and never have to cast it again.
Layouts, Objects, Adapter Complete
Now that we’re done with our layouts, objects, and adapter, it’s time to make use of the new tool we have. On the next and final page, we’ll put it all together and conclude the tutorial.
No comments:
Post a Comment