39

我了解到,为了最大限度地提高 Android 列表视图的效率,您应该只拥有尽可能多的膨胀“行”视图以适应屏幕。一旦视图离开屏幕,您应该在您的getView方法中重用它,检查是否convertView为空。

但是,当您需要 2 种不同的列表布局时,如何实现这个想法?假设它是一个订单列表,一个布局用于已完成的订单,另一个布局用于处理中的订单。

这是我的代码正在使用的想法的示例教程。就我而言,我将有 2 行布局:R.layout.listview_item_product_completeR.layout.listview_item_product_inprocess

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder = null;

if (convertView == null) {
    holder = new ViewHolder();
    if(getItemViewType(position) == COMPLETE_TYPE_INDEX) {
        convertView = mInflator.inflate(R.layout.listview_item_product_complete, null);
        holder.mNameTextView = (TextView) convertView.findViewById(R.list.text_complete);
        holder.mImgImageView = (ImageView) convertView.findViewById(R.list.img_complete);
    }
    else { // must be INPROCESS_TYPE_INDEX
        convertView = mInflator.inflate(R.layout.listview_item_product_inprocess, null);
        holder.mNameTextView = (TextView) convertView.findViewById(R.list.text_inprocess);
        holder.mImgImageView = (ImageView) convertView.findViewById(R.list.img_inprocess);
    }
    convertView.setTag(holder);
} else {
    holder = (ViewHolder) convertView.getTag();
}
    thisOrder = (Order) myOrders.getOrderList().get(position);
    // If using different views for each type, use an if statement to test for type, like above
    holder.mNameTextView.setText(thisOrder.getNameValue());
    holder.mImgImageView.setImageResource(thisOrder.getIconValue());
    return convertView;
}

public static class ViewHolder {
    public TextView mNameTextView;
    public ImageView mImgImageView;
}
4

2 回答 2

84

您需要让适配器的视图回收器知道存在不止一种布局以及如何区分每一行的两者。只需覆盖这些方法:

@Override
public int getItemViewType(int position) {
    // Define a way to determine which layout to use, here it's just evens and odds.
    return position % 2;
}

@Override
public int getViewTypeCount() {
    return 2; // Count of different layouts
}

合并getItemViewType()到里面getView(),像这样:

if (convertView == null) {
    // You can move this line into your constructor, the inflater service won't change.
    mInflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
    if(getItemViewType(position) == 0)
        convertView = mInflater.inflate(R.layout.listview_item_product_complete, parent, false);
    else
        convertView = mInflater.inflate(R.layout.listview_item_product_inprocess, parent, false);
    // etc, etc...

观看 Android 的 Romain Guy在 Google Talks 上讨论视图回收器。

于 2012-11-08T20:33:15.663 回答
9

无需自己设计解决方案,只需覆盖 getItemViewType() 和 getViewTypeCount()。

有关示例,请参阅以下博客文章http://sparetimedev.blogspot.co.uk/2012/10/recycling-of-views-with-heterogeneous.html

正如博客所解释的,Android 实际上并不能保证getView 会收到正确类型的视图。

于 2012-11-08T20:34:49.890 回答