问题复现
背景是这样的,我用的CursorAdapter,然后重写了getViewTypeCount方法
@Override
public int getViewTypeCount() {
return TYPE_COUNT;
}
我又自己实现了一个getItemViewType方法
public int getItemViewType(Cursor cursor) {
。。。省略
if (leadUserId == fromUserId) {
return TYPE_RECEIVE;
} else {// if (leadUserId == toUserId)
return TYPE_SEND;
}
}
我的getView是正常写法,因为牵涉到公司项目,就不贴了,但是写法类似下面的代码:
package com.org.mmp.Play;
import java.util.List;
import com.org.mmp.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class PlayAdapter extends BaseAdapter {
/**
* 标题的item
*/
public static final int ITEM_TITLE = 0;
/**
* 二级菜单的item
*/
public static final int ITEM_INTRODUCE = 1;
private List<ViewItem> mList;
private Context context;
private LayoutInflater inflater;
// 两个样式 两个holder。100就写100holder。。当然你何以把他抽离出来这里先只为了说明问题
class Holder1 {
TextView play_title;
Holder1(View view) {
play_title = (TextView) view.findViewById(R.id.play_title);
}
}
class Holder2 {
TextView play_introduce_title;
ImageView play_iv;
Holder2(View view) {
play_introduce_title = (TextView) view
.findViewById(R.id.play_introduce_title);
play_iv = (ImageView) view.findViewById(R.id.play_iv);
}
}
public PlayAdapter(Context context, List<ViewItem> mList) {
this.context = context;
this.mList = mList;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
System.out.println("mList.size()" + mList.size());
return mList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return mList.get(arg0);
}
//返回 代表某一个样式 的 数值
@Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return mList.get(position).type;
}
//两个样式 返回2
@Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 2;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
Holder1 holder1 = null;
Holder2 holder2 = null;
System.out.println("getView " + position + " " + convertView
+ " type = " + type);
if (convertView == null) {
//选择某一个样式。。
switch (type) {
case ITEM_TITLE:
convertView = inflater.inflate(R.layout.play_item_title, null);
holder1 = new Holder1(convertView);
holder1.play_title.setText(mList.get(position).name);
convertView.setTag(holder1);
break;
case ITEM_INTRODUCE:
convertView = inflater.inflate(R.layout.paly_item_introduce,
null);
holder2 = new Holder2(convertView);
holder2.play_introduce_title
.setText(mList.get(position).address);
convertView.setTag(holder2);
break;
default:
break;
}
} else {
switch (type) {
case ITEM_TITLE:
holder1 = (Holder1) convertView.getTag();
holder1.play_title.setText(mList.get(position).name);
break;
case ITEM_INTRODUCE:
holder2 = (Holder2) convertView.getTag();
holder2.play_introduce_title
.setText(mList.get(position).address);
break;
default:
break;
}
}
return convertView;
}
}
结果一直给我报错,说ViewHolder1不能强制被转换为ViewHolder2....
解决方案:
1.一个致命的错误,我们应该重写getItemViewType(int position)方法,而不是自己写一个,因为这个方法的返回值在ListView的源码中会用,主要是跟它的复用有关系吧,我猜测。具体的原因需要花时间研究一下,今天先mark一下,免得忘记了,后头再补充。