您的位置:首页 > 移动开发 > Android开发

Android ListView使用不同对象加载不同布局

2016-10-31 00:15 423 查看
因为未知原因,突然想到了关于一个 List 集合里面能否添加不同对象的问题,因为我们平时开发过程中,关于List 的比较常规的写法就是:

List<XXX> list = new ArrayList<XXX>();


这让我形成了一种 List 里面就只能添加一种类型的对象的潜在想法(或许是 Java 基础不够扎实)。

所以,我这里用代码确定一下,List 不给定泛型,然后迭代添加两种不同的对象,最后再迭代输出数据,看看是否会有问题,代码如下:

public class MainClass {

private List list = new ArrayList();

public static void main(String args[]) {
MainClass mc = new MainClass();
mc.initData();

for (int i = 0; i < 10; i++) {
Object item = mc.list.get(i);

if (item instanceof TestOther) {
TestOther other = (TestOther) item;
String company = other.getCompany();
String position = other.getPosition();
System.out.println("company : " + company + " , position : " + position);
} else if (item instanceof TestBean1) {
String name = ((TestBean1) item).getName();
String like = ((TestBean1) item).getLike();
System.out.println("name : " + name + " , like : " + like);
}
}
}

private void initData() {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
list.add(new TestOther("Ekoo" + i, "Android Developer" + i));
} else {
list.add(new TestBean1("Test" + i, "Coding" + i));
}
}
}

}


那么我们的运行结果如下:

company : Ekoo0 , position : Android Developer0
name : Test1 , like : Coding1
company : Ekoo2 , position : Android Developer2
name : Test3 , like : Coding3
company : Ekoo4 , position : Android Developer4
name : Test5 , like : Coding5
company : Ekoo6 , position : Android Developer6
name : Test7 , like : Coding7
company : Ekoo8 , position : Android Developer8
name : Test9 , like : Coding9


这里通过打印数据,确定了 List 中可以添加不同对象。

那么,这个问题明确之后,我想到了在之前的工作中,一直以为 ListView 列表数据中不能存有不同的对象,所有数据都只能在同一个对象中定义。这个时候,我们再去尝试一下,利用 List 中可以添加不同对象去测试一下 ListView 中 加载不同的布局。

首先,创建两个不同的对象 :

public class CompanyBean {
private String company;
private String position;
private String address;

public String getCompany() {
return company;
}

public void setCompany(String company) {
this.company = company;
}

public String getPosition() {
return position;
}

public void setPosition(String position) {
this.position = position;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}
}

public class UserBean {

private String name;
private String age;
private String sex;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}
}


然后,我们在 Activity 中初始化一下模拟数据:

private void initData() {
for (int i = 0; i < 20; i++) {
// 这里随机生成 1到10 之间的随机数
int num = (int) (Math.random() * 10);
if (num % 2 == 0) {
UserBean bean1 = new UserBean();
bean1.setName("name" + i);
bean1.setAge(num + "");
bean1.setSex("男");
list.add(bean1);
} else {
CompanyBean bean2 = new CompanyBean();
bean2.setCompany("HzEkoo" + i);
bean2.setAddress("Ypsd201-4(" + i + ")");
bean2.setPosition("Android Developer" + i);
list.add(bean2);
}
}

}


接下来就是定义 Adapter 了。

private class TestAdapter extends BaseAdapter {

private Context context;
private List list;
private LayoutInflater inflater;

public TestAdapter(Context context, List list) {
this.context = context;
this.list = list;
inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public int getItemViewType(int position) {
Object item = list.get(position);
if (item instanceof UserBean) {
return 0;
} else if (item instanceof CompanyBean) {
return 1;
}
return -1;
}

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

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

Object item = getItem(position);

int type = getItemViewType(position);

switch (type) {
case 0:
UserBean userBean = (UserBean) item;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_user, parent, false);
}
TextView tv_name = ViewHolder.get(convertView, R.id.tv_name);
TextView tv_age = ViewHolder.get(convertView, R.id.tv_age);
TextView tv_sex = ViewHolder.get(convertView, R.id.tv_sex);

tv_name.setText(userBean.getName());
tv_age.setText(userBean.getAge());
tv_sex.setText(userBean.getSex());

break;
case 1:
CompanyBean comBean = (CompanyBean) item;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_company, parent, false);
}
TextView tv_company = ViewHolder.get(convertView, R.id.tv_company);
TextView tv_position = ViewHolder.get(convertView, R.id.tv_position);

tv_company.setText(comBean.getCompany());
tv_position.setText(comBean.getPosition());
break;
}

return convertView;
}
}


这个 Adapter 肯定是我最终的调试结果。关于 ViewHolder.get(View , id) 我之前博客 进一步简化你的 ViewHolder 有过介绍。

初期,我的想法是在 getView() 中根据判断 List 对应下标对象的类型 比如:

Object item = list.get(position);
if (item instanceof UserBean) {
UserBean userBean = (UserBean) item;
// do something
} else if (item instanceof CompanyBean) {
CompanyBean comBean = (CompanyBean) item;
// do something
}


这样去判断加载不同的布局,进行数据填充,但是在进行滑动过程中,复用出现了混乱,导致直接闪退。

最终确定选择了使用 getItemViewType() 方法,不过,这个方法在使用的时候也是有个坑,那就是必须要重写getViewTypeCount() 方法,这个以前不怎么用,所以现在才发现这个问题。

最后附上一张效果图:



只是一个简单的测试。

Demo下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: