方案
我正在尝试创建类似于Google Play商店中的精选页面的内容。但不是为类别显示三个项目,而是允许它以两列staggered grid view方式显示任意数量的项目。
因此,每个列表项都有一个标题,其标题和描述后跟自定义视图(让我们调用此SVG,如在交错视图组中),以交错的网格视图方式显示一些子视图。
我有一个名为FeaturedItems
的类,用于保存特色列表中一行的数据。这是一个摘录:
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;
}
}
FeaturedListAdapter
将数据与适配器的getView()
方法中的视图绑定在一起。 getView()
方法如下:
@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;
}
问题
在getView()
方法中,每次返回视图时,它都会删除SVG中的所有子视图,并实例化名为FeaturedItem
的新视图,然后将其添加到SVG中。即使第一行中的特定行中的SVG已填充,当用户从底部向后滚动时,getView()
方法将删除SVG中的所有子视图并实例化要填充的新视图用。
这里效率低下非常明显,列表视图动画在经常滚动时会跳过帧。
我无法在此重复使用convertView
,因为它会在StaggeredViewGroup
中显示错误的特色项目。因此,我必须从StaggeredViewGroup
中删除所有子项并实例化并添加与当前位置相关的视图。
问题
有解决这个问题的方法吗?或者是否有一些替代方法来创建类似于Google Play商店特色页面的页面,但每行都有不同数量的特色商品,因此具有独特的高度?
答案 0 :(得分:2)
应该有一种简单的方法来改进此解决方案。只需重用已经存在的svg子项,如果它们不够就添加新的子项,然后删除任何剩余的子项。
例如(在半伪代码中,方法名称可能不准确):
for (int i = 0; i < items.getItemCount(); i++)
{
if (i < svg.getChildCount())
{
FeaturedItem item = i.getChildAt(i);
// This item might've been set to invisible the previous time
// (see below). Ensure it's visible.
item.setVisibility(View.VISIBLE);
// reuse the featuredItem view here, e.g.
item.setItem(items.getItem(i));
}
else
{
// Add one more item
FeaturedItem item = new FeaturedItem(mContext, items.getItem(i));
...
holder.svg.addView(item);
}
}
// hide surplus item views.
for (int i = items.getItemCount(); i < svg.getChildCount(); i++)
svg.getChildAt(i).setVisibility(View.GONE);
/**
as an alternative to this last part, you could delete these surplus views
instead of hiding them -- but it's probably wasteful, since they may need
to be recreated later
while (svg.getChildCount() > items.getItemCount())
svg.removeChildView(svg.getChildCount() - 1);
**/