View Holder for Android | Techbirds

Now we are going to code the smooth scrolling of our Android ListView.

What’s with the ViewHolder pattern?

The ViewHolder design pattern enables you to access each list item view without the need for the look up, saving valuable processor cycles. Specifically, it avoids frequent call of findViewById() during ListView scrolling, and that will make it smooth.

Without the ViewHolder Design Pattern

Okay, let’s dig it out and see how it works without the ViewHolder pattern.

Let’s take a look at our previous getView() method in ArrayAdapterItem.java

  1. The first time it was loaded, convertView is null. We’ll have to inflate our list item layout and find the TextView via findViewById().
  2. The second time it was loaded, convertView is not null, good! We don’t have to inflate it again. But we’ll use findViewById() again.
  3. The following times it was loaded, convertView is definitely not null. But findViewById() is constantly called, it will work but, it slows down the performance especially if you have lots of items and Views in your ListView.

With the ViewHolder Design Pattern

Now let’s see how it works with the ViewHolder pattern.

  1. The first time it was loaded, convertView is null. We’ll have to inflate our list item layout, instantiate the ViewHolder, find the TextView via findViewById() and assign it to the ViewHolder, and set the ViewHolder as tag of convertView.
  2. The second time it was loaded, convertView is not null, good! We don’t have to inflate it again. And here’s the sweet thing, we won’t have to call findViewById() since we can now access the TextView via its ViewHolder.
  3. The following time it was loaded, convertView is definitely not null. The findViewById() is never called again, and that makes our smooth ListView scrolling.

Let’s Code!

So here it is, we’ll make use of the Android ViewHolder pattern in our ListView (in just 3 steps!).

Step 1: Add the following static class on our ArrayAdapterItem.java file

3 static class ViewHolderItem {

Step 2: Our getView() will look like this:

02 public View getView(int position, View convertView, ViewGroup parent) {
04     ViewHolderItem viewHolder;
07      * The convertView argument is essentially a "ScrapView" as described is Lucas post
09      * It will have a non-null value when ListView is asking you recycle the row layout.
10      * So, when convertView is not null, you should simply update its contents instead of inflating a new row layout.
12     if(convertView==null){
15         LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
16         convertView = inflater.inflate(layoutResourceId, parent, false);
18         // well set up the ViewHolder
19         viewHolder = new ViewHolderItem();
20         viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textViewItem);
22         // store the holder with the view.
23         convertView.setTag(viewHolder);
26         // we've just avoided calling findViewById() on resource everytime
27         // just use the viewHolder
28         viewHolder = (ViewHolderItem) convertView.getTag();
31     // object item based on the position
32     ObjectItem objectItem = data[position];
34     // assign values if the object is not null
35     if(objectItem != null) {
36         // get the TextView from the ViewHolder and then set the text (item name) and tag (item ID) values
37         viewHolder.textViewItem.setText(objectItem.itemName);
38         viewHolder.textViewItem.setTag(objectItem.itemId);

Step 3: For the sake of testing, we’re going to put thousands of items in our ListView. On our MainActivity.java, our showPopUp() will now look like this:

01 public void showPopUp(){
03     // we'll specify the number of items we want our ListView to have.
04     int numberOfItems = 1000;
06     // add your items, this can be done programatically
07     // your items can be from a database
08     ObjectItem[] ObjectItemData = new ObjectItem[numberOfItems];
10     // we'll use a for loop
11     // created objects = number of items specified above
12     for(int x=0; x