解决ScrollView 中的listView只显示一行的问题:

这个是一个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;i<adapter.getCount();++i)
        {
            View item = adapter.getView(i, null, 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<String>(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<String>(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值