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;
}