效果图如下:
ListView适配器代码如下:
public class MyAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater inflater;
/**
* 三种布局所对应的标识,type的值必须从0开始
*/
private static final int TYPE_ONE = 0; // 第一种布局
private static final int TYPE_TWO = 1; // 第二种布局
private static final int TYPE_THREE = 2; //第三种布局
public MyAdapter(Context context) {
mContext = context;
inflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return 9;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
/**
* 此方法返回多少个不同的布局
*/
@Override
public int getViewTypeCount() {
return 3;
}
/**
* 根据数据列表的position返回需要展示的layout的对应type
* type的值必须从0开始
*/
@Override
public int getItemViewType(int position) {
// 0~2位置的item显示第一种布局,3~5位置的item显示第二种布局,6~8位置的item显示第三种布局
// 此处只是为了模拟效果,通常不是这么做的
if (position < 3) {
return TYPE_ONE;
} else if (position < 6) {
return TYPE_TWO;
} else {
return TYPE_THREE;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder1 holder1 = null;
ViewHolder2 holder2 = null;
ViewHolder3 holder3 = null;
// 得到标识
int type = getItemViewType(position);
if (convertView == null) {
// 通过标识加载对应布局
switch (type) {
case TYPE_ONE:
convertView = inflater.inflate(R.layout.item_list_one, null);
holder1 = new ViewHolder1();
holder1.img = convertView.findViewById(R.id.iv_item_one_img);
holder1.txt = convertView.findViewById(R.id.tv_item_one_txt);
convertView.setTag(holder1);
break;
case TYPE_TWO:
convertView = inflater.inflate(R.layout.item_list_two, null);
holder2 = new ViewHolder2();
holder2.img1 = convertView.findViewById(R.id.iv_item_two_img1);
holder2.img2 = convertView.findViewById(R.id.iv_item_two_img2);
holder2.txt = convertView.findViewById(R.id.tv_item_two_txt);
convertView.setTag(holder2);
break;
case TYPE_THREE:
convertView = inflater.inflate(R.layout.item_list_three, null);
holder3 = new ViewHolder3();
holder3.img1 = convertView.findViewById(R.id.iv_item_three_img1);
holder3.img2 = convertView.findViewById(R.id.iv_item_three_img2);
holder3.img3 = convertView.findViewById(R.id.iv_item_three_img3);
holder3.txt = convertView.findViewById(R.id.tv_item_three_txt);
convertView.setTag(holder3);
break;
}
} else {
switch (type) {
case TYPE_ONE:
holder1 = (ViewHolder1) convertView.getTag();
break;
case TYPE_TWO:
holder2 = (ViewHolder2) convertView.getTag();
break;
case TYPE_THREE:
holder3 = (ViewHolder3) convertView.getTag();
break;
}
}
// 设置资源,这里我设置的是死数据,便于演示
switch (type) {
case TYPE_ONE:
holder1.txt.setText("第一种布局");
holder1.img.setImageResource(R.drawable.apple);
break;
case TYPE_TWO:
holder2.txt.setText("第二种布局");
holder2.img1.setImageResource(R.drawable.mango);
holder2.img2.setImageResource(R.drawable.blueberry);
break;
case TYPE_THREE:
holder3.txt.setText("第三种布局");
holder3.img1.setImageResource(R.drawable.strawberry);
holder3.img2.setImageResource(R.drawable.cherry);
holder3.img3.setImageResource(R.drawable.banana);
break;
}
return convertView;
}
// 第一种布局就两个组件
class ViewHolder1 {
private ImageView img;
private TextView txt;
}
class ViewHolder2 {
private ImageView img1, img2;
private TextView txt;
}
class ViewHolder3 {
private ImageView img1, img2, img3;
private TextView txt;
}
}
以上代码有几个问题,这里指出一下:
- 适配器中的数据是死数据,通常是用一个List来显示数据。
- 返回的标识(type),不应该像我上面那样写,应该是根据不同的数据来加载不同的布局,而不是通过位置指定。
- ListView列表的个数应该是显示数据的List的长度。