在 Google 的 Android 开发文档,对于 ScrollView 有如下介绍
1.XML属性
android:fillViewport
这是 ScrollView 独有的属性,用来定义 ScrollView 对象是否需要拉伸自身内容来填充
viewport ,这个 viewport 应该是指布局文件中为ScrollView指定的区域。
这个属性也可以在代码中通过 setFillViewport(boolean) 方法指定
android:overScrollMode
这是继承于 View 的属性,也很常用。用于定义 over-scrolling behavior
也就是滑动到超出内容边缘的时候的行为。
这个属性很奇特,在 Android 官方文档的 View 的 XML 属性中找不到介绍
但既然能用,肯定在R.attrs文件中有定义,在 Android 平台的源码及资源文件中
一定能找到
随便找一个项目,在External Libraries 中找到 Android Platform 的源码及资源文件
也就是 android.jar 和 res 文件夹,在 res->values->attrs 文件中查找 overScrollMode
最终在
<declare-styleable name="View"></declare-styleable>标签中找到
这证明它的确是 View 的属性
这说明官方文档也不是最完整准确的。或者也有其他原因,但是暂时不知道。
2.ScrollView 中嵌入 ListView 引发的错误
ScrollView 中只能包含一个子布局。如果这个子布局中恰好还有一个 ListVie 组件
那么这个 ListView 的绘制会出现问题 ---- 无论在 xml 布局中如何指定 ListView
的宽高,ListView 就只能显示一条数据,不显示其他数据
解决办法就是在代码中动态指定 ListView 的绘制参数 LayoutParams ,将每一个
item 的高度累加,计算出总的高度,赋值给 ListView
具体代码如下:
public void setListViewHeightBasedOnChildren(ListView listView) {
// 获取ListView对应的Adapter
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0, len = listAdapter.getCount(); i < len; i++) {
// listAdapter.getCount()返回数据项的数目
View listItem = listAdapter.getView(i, null, listView);
// 计算子项View 的宽高
listItem.measure(0, 0);
// 统计所有子项的总高度
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1) + 5);
// listView.getDividerHeight()获取子项间分隔符占用的高度
// params.height最后得到整个ListView完整显示需要的高度
listView.setLayoutParams(params);
}