ScrollView嵌套ListView冲突问题的解决方案

Android开发中,如果一个页面上显示的内容过多,我们会在最外部嵌套一个ScrollView,将里面的内容包裹起来,以打到可以上下滑动的效果,
但是如果此时子控件有listview,gridview等可滑动的控件时,就会出现问题。

问题一:数据显示不全

先看效果图,正常显示的listview:

这里写图片描述
代码如下:

    private String[] mStrings = { "Abbaye de Belloc",
            "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
            "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu",
            "Airag", "Airedale", "Aisy Cendre", "Allgauer Emmentaler",
            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam",
            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
            "Allgauer Emmentaler" };
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.listview);
        listView.setAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mStrings));
    }

如果我们给listview的外部嵌套一个ScrollView会发生什么情况呢?

  <ScrollView 
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         >
    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    </ScrollView>

运行结果如下:

这里写图片描述
原来那么多数据怎么只能显示一条了。
原因就是当在ScrollView中嵌套listview时,系统就无法计算listview的高度了。
解决方案:
1.重写listview或者gridview

    /**
     * 重写该方法,达到listview适应gridview的效果
     */
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
        MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
        }

2.动态设置listview的高度

    /**
     * 根据条目的数量和高度动态设置listview的高度
     */
     public static void setListViewHeightBasedOnChildren(ListView listView) {  
            ListAdapter listAdapter = listView.getAdapter();   
            if (listAdapter == null) {  
                return;  
            }  
            int totalHeight = 0;  
            for (int i = 0; i < listAdapter.getCount(); i++) {  
                View listItem = listAdapter.getView(i, null, listView);  
                listItem.measure(0, 0);  
                totalHeight += listItem.getMeasuredHeight();  
            }  
            ViewGroup.LayoutParams params = listView.getLayoutParams();  
            params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));  
            listView.setLayoutParams(params);  
        }  

在实际开发中,基本上都是用第一种方法,首先,比较简单,不用计算,不用关心条目的多少,然后就是我们看第二种方法里面有一行代码,listItem.measure(0, 0);,就是我们手动的去调用了measure方法去测量条目的高度,但是这样测量出来的高度是有问题的,和我们实际代码中写的高度不一致,有些偏差,下面看官方文档的解释:

View的大小由width和height决定。一个View实际上同时有两种width和height值。

第一种是measure width和measure height。他们定义了view想要在父View中占用多少width和height(详情见Layout)。measured height和width可以通过getMeasuredWidth() 和 getMeasuredHeight()获得。

第二种是width和height,有时候也叫做drawing width和drawing height。这些值定义了view在屏幕上绘制和Layout完成后的实际大小。这些值有可能跟measure width和height不同。width和height可以通过getWidth()和getHeight获得。

所以说,第二种那个方法是有一些问题的,开发中不建议使用。
问题二:打开套有listview的scrollview页面,默认起始位置不是最顶部
解决方案:
1.让listview或者gridview不获取焦点
gridview.setFocusable(false)
注意:在布局文件中设置android:focusable =”false”不起作用
2.使scrollview划动到最顶部
scrollView.smoothScrollTo(0,0)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值