解决ScrollView跟ListView或GridView嵌套时的问题

来源:互联网 发布:apache arrow 编辑:程序博客网 时间:2024/04/28 14:23

以下文章转自@安卓泡面


在工作中,曾多次碰到ScrollView嵌套ListView的问题,网上的解决方法有很多种,但是杂而不全。我试过很多种方法,它们各有利弊。

在这里我将会从使用ScrollView嵌套ListView结构的原因、这个结构碰到的问题、几种解决方案和优缺点比较,这4个方面来为大家阐述、分析、总结。

实际上不光是ListView,其他继承自AbsListView的类也适用,包括ExpandableListView、GridView等等,为了方便说明,以下均用ListView来代表。


一、 为什么要使用ScrollView嵌套ListView的奇怪的结构        


ScrollView和ListView都是滚动结构,按理说,这两个控件在UI上的功能是一样的,但是看看下面这个设计:

       141.png


    这是天猫商城的确认订单的页面,ScrollView中嵌套了ExpandableListView,ExpandableListView上面有固定的一些控件,下面也有固定的一些控件,整体又要能够滚动。    列表数据要嵌在固定数据中间,并且作为整体一起滚动,有了这样的设计需求,于是就有了ScrollView嵌套ListView的奇怪结构。



二、 ScrollView、ListView嵌套结构碰到的问题   


不多说,直接看失败例子:   



  •     <ScrollView
  •     android:id="@+id/act_solution_1_sv"
  •     android:layout_width="fill_parent"
  •     android:layout_height="fill_parent">
  •     <LinearLayout
  •         android:layout_width="fill_parent"
  •         android:layout_height="wrap_content"
  •         android:orientation="vertical">
  •         <TextView
  •             android:layout_width="fill_parent"
  •             android:layout_height="wrap_content"
  •             android:text="\nListView上方数据\n" />

  •         <ListView
  •             android:id="@+id/act_solution_1_lv"
  •             android:layout_width="fill_parent"
  •             android:layout_height="wrap_content">

  •         </ListView>

  •         <TextView
  •             android:layout_width="fill_parent"
  •             android:layout_height="wrap_content"
  •             android:text="\nListView下方数据\n" />
  •     </LinearLayout>
  •     </ScrollView>






    ScrollView中只能放一个控件,一般都放LinearLayout,orientation属性值为vertical。在LinearLayout中放需要呈现的内容。ListView也在其中,ListView的高度设为适应自身内容(wrap_content)。粗略一看,应该没有什么问题。但是看下面的实际效果图:
  

       142.png


    图中黑框的部分就是ListView,里面放了20条数据,但是却只显示了1条。
    控件的属性设置上没有问题,但是为什么没有按照我的想法走呢?
    看看下面这个图:
    143.png



    是否有点明白了呢?原因就是scroll事件的消费处理以及ListView控件的高度设定问题。


解决方案:

自定义可适应ScrollView的ListView
    这个方法和上面的方法是异曲同工,方法3是自定义了LinearLayout以取代ListView的功能,但如果我脾气就是倔,就是要用ListView怎么办?那就只好自定义一个类继承自ListView,通过重写其onMeasure方法,达到对ScrollView适配的效果。
    下面是继承了ListView的自定义类:

  • import android.content.Context;
  • import android.util.AttributeSet;
  • import android.widget.ListView;

  • public class ListViewForScrollView extends ListView {
  •     public ListViewForScrollView(Context context) {
  •         super(context);
  •     }

  •     public ListViewForScrollView(Context context, AttributeSet attrs) {
  •         super(context, attrs);
  •     }

  •     public ListViewForScrollView(Context context, AttributeSet attrs,
  •         int defStyle) {
  •         super(context, attrs, defStyle);
  •     }

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


GridView跟上面的解决方案一样。
1 0
原创粉丝点击