DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Key Takeaways From Integrating a RAG Application With LangSmith
  • Improving Java Application Reliability with Dynatrace AI Engine
  • Enabling Single-Sign-On in SaaS Application
  • Reimagining Innovation: How Citizen Application Development is Reshaping the Modern Enterprise

Trending

  • How to Save Money Using Custom LLMs for Specific Tasks
  • Mastering Fluent Bit: Beginners' Guide for Contributing to Our CNCF Project Website
  • Stop Debugging Glue Jobs Manually: Building an Agentic Observability Layer for Data Pipelines
  • Observability for Agents and Workflows: Tracing Prompts, Tool Calls, and Business Outcomes End-to-End

Optimizing Your ListView with the ViewHolder Pattern

By 
Justin Saliba user avatar
Justin Saliba
·
Oct. 03, 13 · Interview
Likes (2)
Comment
Save
Tweet
Share
93.0K Views

Join the DZone community and get the full member experience.

Join For Free

The ListView is a widget used extensively in Android applications to display data in a structured fashion. It is also a view that can be quite tricky to optimize, and making your applications feel less jittery is extremely important. When developing an application, a developer has to keep in mind the wide range of hardware on which Android runs. Nowadays most high end phones and tablets are equipped with at least a dual core processor, which can handle unoptimized code at tolerable speeds. However, a large percentage of Android devices are still using single core processors with limited memory. This blog aims to deliver one form of optimization that developers can place in their code at next to no effort.

The ViewHolder pattern is a pattern that a developer can use to increase the speed at which their ListView renders data. The reason for this improvement is that the number of times which the findViewById method is invoked is drastically reduced, existing views do not have to be garbage collected and new views do not have to be inflated. A typical ListView adapter contains the following method signature:

public View getView (int position, View convertView, ViewGroup parent)

The ‘position’ integer stores the position of the current item within the adapter’s data set. The ‘convertView’ field is a reference to the old view that we are planning to reuse. This is the field that we use to implement our optimisation. It is extremely important to use this variable. Not doing so eventually leads to an OutOfMemoryException. This happens because internally a ListView keeps a reference to views it has already seen. Not reusing the ‘convertView’ field will continuously add new views to the ListView, causing a noticeable slowdown of your application and eventually lead to your application crashing. The ‘parent’ field is a reference to the parent view that this view is eventually attached to. Consider the following class:

public class Person {
    private String name;
    private String surname;
    private Bitmap image;

    public Person(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }

    public String getName() {
        return name;
    }

    public String getSurname() {
        return surname;
    }

    public Bitmap getImage() {
        return image;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public void setImage(Bitmap image) {
        this.image = image;
    }
}

Now we want to print a list of persons, all of whom are paired with an image. We need one ImageView for the image, and two TextViews for the name and surname fields. Our ViewHolder class would look something like the following and reside as a static inner class inside our Activity (or Fragment):

static class ViewHolder {
    private TextView nameTextView;
    private TextView surnameTextView;
    private ImageView personImageView;
}

We then implement our own ArrayAdapter for our list of persons that we want to display:

private class PersonsAdapter extends ArrayAdapter<Person> {

    ...

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_entry, null);
            holder = new ViewHolder();
            holder.nameTextView = (TextView) convertView.findViewById(R.id.person_name);
            holder.surnameTextView = (TextView) convertView.findViewById(R.id.person_surname);
            holder.personImageView = (ImageView) convertView.findViewById(R.id.person_image);
            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }

        Person person = getItem(position);

        holder.nameTextView.setText(person.getName());
        holder.surnameTextView.setText(person.getSurname());
        //holder.personImageView.setImageBitmap(person.getImage());

        return convertView;
    }
}

Note that I have purposefully commented out the loading of bitmaps in the ListView. This is something that has given a lot of trouble to developers and might be something we could address in a future blog post. Given the relatively small heap size that Android applications are allowed to access, developers need to take several steps to display multiple images on screen in an efficient manner. Downsampling of images is just one example of many possible optimizations.


application

Published at DZone with permission of Justin Saliba. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Key Takeaways From Integrating a RAG Application With LangSmith
  • Improving Java Application Reliability with Dynatrace AI Engine
  • Enabling Single-Sign-On in SaaS Application
  • Reimagining Innovation: How Citizen Application Development is Reshaping the Modern Enterprise

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook