思路Ⅰ:添加 Head View(推荐)
调用 ListView#addHeadView() 或 addFooterView() 来定制头尾特殊布局。
缺点:
数据下标影响。ListView的第一个元素变成了Button,要注意在adapter的getView()当中特别处理下标为0的情况。包括UI显示和事件监听。
GridView控件官方没有提供addHeadView()方法。
备注:
其实AOSP项目中Gallery APP已经有ASIS提供的GridView的addHeadView()方法,实际使用过,有显示的问题,可能这也是AOSP没有将这个API公开的原因之一
如果不是GridView的话,个人比较推荐这种方案。
思路Ⅱ:Adapter#getView() 里根据 Index 灵活定制 layout
当 index 为 0 的时候加载 Button 布局,其他为一般布局,具体不再展开。
思路Ⅲ:ScrollView 嵌套 Button + ListView
当上述两种思路均无法满足需求的时候可以考虑此思路,缺点不少,但不失是一个折衷方案。
缺点:
UI 问题:Android官方不建议在ScrollView内嵌套ListView或GridView,因为有如下Bug:
ListView在ScrollView中的高度会显示不完整,需要覆写ListView的onMeasure()复写最大 Size 的 Spec 实例解决这个问题
ListView在ScrollView中不能实时的滚动到顶部,需要在onWindowFocusedChanged()中手动调节ListView的位置
大体:
public class ListViewForScrollView extends ListView { ... @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Int 值 32 位右移 2 位之后作为 Size 创建 Spec 实例 // Spec 一共 32 位,高 2 位需要放 Mode // ListView 高度按照全部展开去计算 int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
性能影响:覆写ListView的onMeasure()会导致ListView的项目在只看到部分item的情况下,实际上已经将全部item加载完毕,会对性能造成影响
其他影响:正因为覆写ListView的onMeasure()导致ListView的全部item加载完毕,getFirstVisiblePosition()永远是0,getLastVisiblePosition永远是item总数。这种情况下,要用到getFirstVisiblePosition()和getLastVisiblePosition()的话,得到的结果是不正确的。
优点:
并不会影响到加载的数据的下标,不用在adapter的getView()当中特别处理下标。