带有viewholder的Android ArrayAdapter每次都会给出不同的结果

时间:2014-10-11 17:46:21

标签: android

我有一个用于listview的自定义ArrayAdapter。除了一些图形内容(如背景和对齐)之外,我有两种类型的行具有几乎相同的内容。

这就是它的样子:

public class ChatAdapter extends ArrayAdapter<MessageSource.Message> {

private Context context;
private List<MessageSource.Message> items;
private int deviceId;

public ChatAdapter(Context context, int layoutResourceId, List<MessageSource.Message> items, int deviceId) {
    super(context, layoutResourceId, items);
    this.context = context;
    this.items = items;
    this.deviceId = deviceId;
}

static class ViewHolder {
    protected TextView from;
    protected TextView message;
    protected TextView time;
}

@Override
public View getView(int p, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    ViewHolder viewHolder ;
    if(convertView == null) {
        if (items.get(p).deviceId == deviceId) {
            convertView = inflater.inflate(R.layout.chat_row_right, parent, false);
        } else {
            convertView = inflater.inflate(R.layout.chat_row_left, parent, false);
        }
        viewHolder = new ViewHolder();
        viewHolder.from = (TextView) convertView.findViewById(R.id.bubble_from);
        viewHolder.message = (TextView) convertView.findViewById(R.id.bubble_message);
        viewHolder.time = (TextView) convertView.findViewById(R.id.bubble_time);

        viewHolder.from.setTypeface(Font.rLight(context));
        viewHolder.message.setTypeface(Font.rLight(context));
        viewHolder.time.setTypeface(Font.rLight(context));

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.from.setText(items.get(p).nickName);
    viewHolder.message.setText(items.get(p).message);
    viewHolder.time.setText(DateUtils.getRelativeTimeSpanString(items.get(p).created * 1000, System.currentTimeMillis(), 0));

    return convertView;
}
}

使用此行我可以确定要使用的布局:

if (items.get(p).deviceId == deviceId) {

但它似乎被随机忽略并选择布局,因为它看起来合适。 我在这里做错了什么想法?

1 个答案:

答案 0 :(得分:2)

仅在convertView == null时检查deviceId。要获得正确的结果,您还应该检查convertView提供给您的布局是否包含哪些布局,如果格式不正确,则需要检查新布局。

幸运的是listview支持像你这样的情况 - 覆盖getViewTypeCount和getItemViewType,如下所示:

@Override
public int getItemViewType( int p ) {
    return items.get(p).deviceId == deviceId ? 0 : 1;
}

@Override
public int getViewTypeCount() {
    return 2;
}

然后您不必检查视图类型,因为listview会为您处理此检查 - 它会缓存您单独使用的所有视图类型,并将正确的视图类型传递给您的getView方法。