这个是一个Bug,网上列出的通常的解决办法有两个:
第一种是通过重写ListView的onMeasure方法来达到目的,让listView不具有滑动性,而恰好ScrollView是可以滑动的,因此互相弥补:
具体code如下:
public class MyListView extends ListView{
//重写ListView与GridView,让其失去滑动特性
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//由于32位数中最高两位表示模式,也就是MeasureSpec.AT_MOST 后三十位表示的是组件大小的值,我们赋值为Integer.MAX_VALUE >> 2也就是极限最大值,
//然后通过这个函数组合成一个我们需要的高度测量值,因此此时由于height是最大值了,listview就不会具有滑动性了
int mExpandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, mExpandSpec);
}
}
第二种方式是通过自己计算出ListView 的高度,然后调用ListView的setLayoutParams函数设置新的视图。具体Code:
注意:这个方案中子ListView的每个Item必须是LinearLayout,不能是其他的,因为其他的Layout(如RelativeLayout)没有重写onMeasure(),所以会在onMeasure()时抛出异常。
//注意:这个方案中子ListView的每个Item必须是LinearLayout,不能是其他的,因为其他的Layout(如RelativeLayout)没有重写onMeasure(),所以会在onMeasure()时抛出异常。
//当我们的ScrollView中有listView的时候,会出现一个bug,那就是listview只会显示一行,因此可以用下面的方式解决这个问题
private void setListViewHeight(ListView listView)
{
ListAdapter adapter = listView.getAdapter();
if(adapter == null)
return;
int totalHeight=0;
for(int i=0;inull, listView);
item.measure(0, 0);
totalHeight+=item.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
// listView.getDividerHeight()获取子项间分隔符占用的高度
// params.height最后得到整个ListView完整显示需要的高度
params.height = totalHeight+(listView.getDividerHeight()*(adapter.getCount()-1));
listView.setLayoutParams(params);
}
因此如果是调用第一种方式,我们的code写法应该是:
public class MainActivity extends Activity {
private MyListView mListView;
private String[] mDatas = new String[30];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (MyListView) findViewById(R.id.listView1);
for(int i=0;i<30;++i){
mDatas[i]="test"+i;
}
mListView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, mDatas));
//setListViewHeight(mListView);
}
xml的写法应该是:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFE1FF"
android:orientation="vertical" >
<ScrollView
**android:fadeScrollbars="false"**
android:layout_width="match_parent"
android:layout_height="match_parent" >
<**LinearLayout**
android:layout_width="match_parent"
android:layout_height="match_parent" >
<**com.qs.scrollview.MyListView**
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="vertical"
android:fadingEdgeLength="5dp" />
LinearLayout>
ScrollView>
LinearLayout>
但是如果是第二种方式,我们的写法就应该是:
public class MainActivity extends Activity {
private ListView mListView;
private String[] mDatas = new String[30];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.listView1);
for(int i=0;i<30;++i){
mDatas[i]="test"+i;
}
mListView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, mDatas));
setListViewHeight(mListView);
}
}
xml的写法应该是:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFE1FF"
android:orientation="vertical" >
<ScrollView
**android:fadeScrollbars="false"**
android:layout_width="match_parent"
android:layout_height="match_parent" >
<**LinearLayout**
android:layout_width="match_parent"
android:layout_height="match_parent" >
<**ListView**
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="vertical"
android:fadingEdgeLength="5dp" />
LinearLayout>
ScrollView>
LinearLayout>
需要注意的是,必须在listView上面嵌套一个LinearLayout ,因为它重写了onMeasure方法,因此能让我们调用item.measure(0, 0);而不会抛出异常
在这里做个笔记,以备不时之需!
代码code 示例 百度云盘:
链接:http://pan.baidu.com/s/1qbFsi 密码:yskd