The scenario
I'm trying the create something akin to the featured page on Google Play Store. But instead of showing three items for a category I'm allowing it show any number of items in a two column staggered grid view fashion.
So each list item has a header that has a title and a description followed by a custom view (lets call this SVG, as in Staggered View Group) that shows some number of children views in a staggered grid view fashion.
I have a class called FeaturedItems
that hold the data for a row in the featured list. Here is an extract:
public class FeaturedItems {
private String mName;
private String mDescription;
private ArrayList<Object> mList;
public FeaturedItems(String name, String description, Object... items) {
mName = name;
mDescription = description;
mList = new ArrayList<Object>();
for (int i = 0; i < items.length; i++) {
mList.add(items[i]);
}
}
public int getItemCount() {
return mList.size();
}
public Object getItem(int position) {
return mList.get(position);
}
public String getFeatureName() {
return mName;
}
public String getFeatureDescription() {
return mDescription;
}
}
The FeaturedListAdapter
binds the data with the views in the getView()
method of the adapter. The getView()
method is as follows:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
FeaturedItems items = getItem(position);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(mResource, null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.list_item_shop_featured_title);
holder.description = (TextView) convertView.findViewById(R.id.list_item_shop_featured_description);
holder.svg = (StaggeredViewGroup) convertView.findViewById(R.id.list_item_shop_featured_staggered_view);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(items.getFeatureName());
holder.description.setText(items.getFeatureDescription());
// HELP NEEDED HERE
// THE FOLLOWING PART IS VERY INEFFICIENT
holder.svg.removeAllViews();
for (int i = 0; i < items.getItemCount(); i++) {
FeaturedItem item = new FeaturedItem(mContext, items.getItem(i));
item.setOnShopActionsListener((ShopActions) mContext);
holder.svg.addView(item);
}
return convertView;
}
The problem
In the getView()
method, each time a view is returned, it removes all the child views in the SVG and instantiates new views called FeaturedItem
that are then added to the SVG. Even if the SVG in a particular row, say first row, was populated, when the user scrolls back to it from the bottom, the getView()
method will remove all the children views in the SVG and instantiates new views to be populated with.
The inefficiency here is very obvious, and the list view animation skips frames when scrolled quite often.
I can't just reuse the convertView
here because it shows the wrong featured items in the StaggeredViewGroup
. Therefore I have to remove all children from the StaggeredViewGroup
and instantiate and add the views that are relevant to the current position.
The question
Is there a way around this problem? Or are there some alternative approaches to creating a page similar to the Google Play Store featured page, but with each row having different number of featured items thus having its unique height?