Optimize lists a 175%
two operations are expensive when we create custom lists: Inflate
(covered on the tip 23) and findByViewId(int)
. We can avoid call to this second operation saving the views used for every row in a wrapper.
This pattern implies use a Model and a Wrapper. The Model will save the information of every row and the Wrapper
will save the Views. We need to save the wrapper in every row view using the properties getTag()
and setTag(Object)
.
This example will use only one value in the model and a TextView
in the wrapper, but you can extend it as much as you wish.
// Model: Item.java
public class Item {
private String value = null;
public String getValue() {
if (this.value == null) {
this.value = "";
}
return this.value;
}
public void setValue(String value) {
this.value = value;
}
}
// Wrapper: ItemWrapper.java
public class ItemWrapper {
private View row = null;
private TextView mTextView = null;
public ItemWrapper(View row) {
this.mRow = row;
}
private TextView getMTextView() {
if (this.mTextView == null) {
this.mTextView = (TextView) {
this.row.findViewById(R.id.your_row_layout_textview);
}
}
return this.mTextView;
}
public void populate(Item item) {
this.getMTextView().setText(item.getValue());
}
}
// Adapter: MyAdapter.java
private List<Item> items;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ItemWrapper wrapper = null;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.your_row_layout, null);
wrapper = new ItemWrapper(row);
row.setTag(wrapper);
} else {
wrapper = (ItemWrapper) row.getTag();
}
// Populate row
wrapper.populate(items.get(position));
return row;
}
NOTE: related post: Optimize lists a 150%