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

来源:互联网 发布:矩阵防御1 编辑:程序博客网 时间:2024/04/20 17:42

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)

0 0
原创粉丝点击