我有一个用于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) {
但它似乎被随机忽略并选择布局,因为它看起来合适。 我在这里做错了什么想法?
答案 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方法。