看到这个标题首先想到的可能就是聊天页面了,当然,使用最多的估计也是它。我们知道,在聊天的过程中,收到消息和发送的消息的布局是不一样的,这就要求我们需要对接受和发送设置不同的Item布局。和单一布局不同的是,多布局如果使用单一布局的处理方式,那么将一定会出现复用问题,不是消息内容的复用,而是布局的复用。
效果
实现
下面我们通过迭代式的开发,来一步一步完成我们的需求。首先我们来看一下处理普通ListView的方式,伪代码如下:
PS:这里我们只贴一下getView()的源码。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder myHolder = null;
if (convertView == null) {
convertView = getLayoutInflater().from(context).inflate(R.layout.item_layout, parent, false);
myHolder.childView = (ViewType)convertView.findViewById(R.id.xx);
myHolder.childView2 = ...
... 获取所有的子View...
convertView.setTag(myHolder);
} else {
myHolder = (MyViewHolder)convertView.getTag();
}
// 设置Item中的View的内容
...
return convertView;
}
上面的代码基本上是实现getView()的一个模板,在单一布局的情况下,这中处理方式基本都是通用的,但是我们需要加载的是不同的布局。那么就需要进行一番修改,代码如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder myHolder = null;
if (convertView == null) {
// 根据数据的类型加载不同的字段
int type = ListData.get(position).type;
if (type == MSG_TYPE_RECEIVE) {
convertView = getLayoutInflater().from(context).inflate(R.layout.item_conversation_left_layout, parent, false);
} else {
convertView = getLayoutInflater().from(context).inflate(R.layout.item_conversation_right_layout, parent, false);
}
myHolder.childView = (ViewType)convertView.findViewById(R.id.xx);
myHolder.childView2 = ...
... 获取所有的子View...
convertView.setTag(myHolder);
}
// 后面的代码和前面一样
...
}
上面的代码虽然能够加载不同的布局,但却没有解决复用问题。看来还得继续进行改造。这次我们保留了加载不同布局的部分,着重对复用进行修改,代码如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolde