常见问题,类似订单列表这种,每个大item,有相同布局,但有些头部和底部View没办法根据数据类型复用,如下图。很多人采用列表嵌套列表来做,但这样会造成UI卡顿,因为滑动的时候外层列表的Item需不断的去设置内层列表的adapter。
机智的我觉得肯定是有办法,通过一个ListView或RecyclerView有多种item布局来实现。
通常后端返回数据是array里面嵌套了array。
{
data:[
{//大item
order_num:"5236872983023",
products:[
{//小item
product_id:"352787398209380"
}
]
}
]
}
想要用一个ListView或RecyclerView有多种item布局来实现,那数据必须是一个List。那我们为什么不把后端返回的数据,重新包装下呢。
思路:
按照UI结构,有头部、中间子列表item、底部三种布局类型,那就要三种数据类型。
然而后端返回的数据中并没有头部和底部这两种数据,那么我们可以去伪造出这两种数据,我们可以把后端返回的数据提取出来然后增加头部和底部数据装进一个List容器中。
我们可以自定义一个类:
/**
* 类似订单列表 每个大item有相同头部底部布局,中间小item列表
* 二次封装数据 解决列表嵌套 避免UI卡顿
* Created by hucanhui on 2017/2/28.
*/
public class MultipleTypeDataHelper {
public List<MultipleTypeData> datas = new ArrayList<MultipleTypeData>();//二次封装的数据容器
public void add(MultipleTypeData multipleTypeData){
datas.add(multipleTypeData);
}
public void remove(MultipleTypeData multipleTypeData){
datas.remove(multipleTypeData);
}
public void remove(int index){
datas.remove(index);
}
/**
* 添加不同类型的数据
* @param type 数据类型
* @param object 对应数据
*/
public void add(int type, Object object){
MultipleTypeData multipleTypeData = new MultipleTypeData();
multipleTypeData.setData(object);
multipleTypeData.setType(type);
add(multipleTypeData);
}
public List<MultipleTypeData> getDatas() {
return datas;
}
public void setDatas(List<MultipleTypeData> datas) {
this.datas = datas;
}
class MultipleTypeData{
private int type;//自行定好 type值对应的类型
private Object data;//数据 大items数据 或小item数据
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
}
代码有注释略看应该就懂。
然后我们,用for循环遍历后端返回的数据,add到这个到这个容器中,按照UI结构顺序,因先添加头部的数据,然后再添加中间列表item的数据,最后添加底部的数据。示例:
List<List> listList = new ArrayList<>();//假设这是后端返回数据
MultipleTypeDataHelper helper = new MultipleTypeDataHelper();
//二次数据封装示例 根据后端返回数据结构自行调整 这边只是个思路
int outSize = listList.size();
for (int i = 0; i < outSize; i++) {
List list = listList.get(i);
helper.add(1, list);//大item头部 类型为1
int innerSize = list.size();
for (int j = 0; j < innerSize; j++) {
helper.add(2, list.get(i));//中间小item
}
helper.add(3, list);//底部
}
我们已经把所有布局的数据按顺序放进一个List里面了,这下应该就非常好办了吧,不管你用ListView还是RecyclerView,在Adapter中根据List中取出数据的类型返回对于布局就好。以RecyclerView为例:
@Override
public int getItemViewType(int position) {
return help.datas.get(position).getType();//返回对应类型
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
switch (viewType){//这里根据不同类型创建ViewHolder
case 1:
break;
case 2:
break;
case 3:
break;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
int type = getItemViewType(position);
switch (type){//根据不同类型绑定holder
case 1:
break;
case 2:
break;
case 3:
break;
}
Game Over! 大家可根据实际开发情况改,最重要的一个是拼装数据。其实一些有时间轴做头部的列表,也可以用类似的做法,集思广益。