Use ViewHolder Pattern in Adapters

ID

java.android_view_holder

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

medium

Resource

Efficiency

Language

Java

Tags

android, best-practice, efficiency

Description

Reports unconditional calls to inflate() inside getView() methods of Android adapter classes (BaseAdapter, ArrayAdapter, CursorAdapter). The convertView parameter should be reused when non-null, inflating a new layout only when it is null.

Rationale

The Android framework passes a recycled convertView to getView() for reuse. Ignoring it and inflating a new layout on every call defeats the view recycling mechanism, causing excessive object creation, increased GC pressure, and janky list scrolling.

// Bad: unconditional inflation
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(context);
    convertView = inflater.inflate(R.layout.item, null); // always inflates
    return convertView;
}

Remediation

Check whether convertView is null before inflating. Use the ViewHolder pattern to cache child view references and avoid repeated findViewById() calls.

// Good: reuse convertView when available
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.item, parent, false);
        holder = new ViewHolder(convertView);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.bind(getItem(position));
    return convertView;
}