在Android开发中,可能会遇到一个可滚动且布局比较复杂的界面,但它并不是一个纯粹的List,类似如下图:

demo.png
通常实现方法可以直接用一个ScrollView将所有内容包起来,里面是列表的部分在代码中用动态添加布局的方式实现;或者外层ScrollView,里面列表部分用ListView(或RecyclerView)实现,但这样需要解决滑动冲突问题(有时并不能很好解决)……所以最好不要同时使用ScrollView和ListView(或RecyclerView),但如果单使用ScrollView,每次滑动返回时都会重新动态加载,如果页面图片比较多,可能会造成卡顿,所以要自己做缓存判断的处理,而ListView自带有缓存机制,处理相对比较方便。

那这种不是纯粹List的布局用ListView如何实现?它也并不是只是头尾部分不相同而已(ListView可以addHeader, addFooter), 所以要将它分成一个个不同类型的item。下面展示一个之前公司项目所实践用到的一个例子,效果demo如图:

ComplexListViewDemo.gif

嗯,其实也没什么难度,也就是如何将整个页面的划分为不同的item,并处理不同的数据模块,使代码更加模块化,直观而且更容易维护。其中HomeAdapter是处理List不同item的适配器,相对于普通适配器多了一个getItemViewType()方法的处理;ImageAdapter是图片轮播适配器;HomeItem是整个页面的数据模型,包含了所有item的不同数据模型,接收到网络数据时需要对数据加工再设置到HomeItem,然后根据ItemType 作为不同item类型的判断,再根据不同item获取对应的字段;各个item的数据处理是在单独一个ViewHolder上处理……

1
2
3
4
5
6
7
8
9
10
class HomeItem{
private ItemType itemType; //作为不同item类型的判断
private String tagName;
private Special special;
private Ad ad;
private MenuPo[] menuPos;
private List<MealShow> mealShowList;
private List<TalentShow> talentShowList;
//……
}

另外,可以看到当上滑时,搜索框会悬停在顶部,此处用到一个小技巧,障眼法,单独的搜索框一直在顶部,通过在滑动的过程中控制它的显示和隐藏即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mListView.setOnScrollListener(new AbsListView.OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView absListView, int i){
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
if (firstVisibleItem >= 1) {
rlSearchBar.setVisibility(View.VISIBLE);
} else {
rlSearchBar.setVisibility(View.GONE);
}
}
});

Talk is cheap, read the code.

Github: ComplexListViewDemo