ScrollView嵌套ListView滑动冲突的简单解决方法

ScrollView和ListView这两个控件想必你们都不会陌生,可是这二者嵌套使用的时候就会出现麻烦。好比,咱们若是想在ListView下面添加其余的布局或者控件,而后想让它们做为一个总体均可以滑动的话,最常想到的就是用一个ScrollView把它们包裹起来。想法彷佛很美好,可是现实就有点残酷了。咱们能够写一个小例子体验一下。java

首先建立一个Activity,在它的布局文件上放置一个ListView:android

<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
    tools:context="com.lin.mr.mystudy.scrollview.TestActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>

</LinearLayout>

而后在代码中使用for循环生成一些数据,并使用ArrayAdapter适配数据。这里容许我偷一下懒,ListView的item布局直接使用Android提供的R.layout.simple_list_item_1,而没有本身去自定义。ide

public class TestActivity extends Activity {
    private ListView listView;
    private ArrayList<String> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        listView = (ListView) findViewById(R.id.listView);
findViewById(R.id.ll_container);

        list = new ArrayList<>();
        //生成须要显示到ListView中的数据
        for (int i = 0; i < 30; i++) {
            list.add("这是数据"+i);
        }
        //使用ArrayAdapter适配数据
        listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,list));
    }
}

确保你当前的Activity为启动Activity,而后运行App,能够看到以下的效果:布局

一个简单的ListView

好,看起来没有问题,可是若是这时咱们须要在这个ListView的头部或者底部添加一些控件,而后让它们总体均可以滑动呢?咱们能够先这样试试:this

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
    tools:context="com.lin.mr.mystudy.scrollview.TestActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            
        </ListView>

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮一" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮二" />

    </LinearLayout>

</ScrollView>

在ListView的头部和底部加了几个控件,而后把全部的控件都用一个线性布局包裹起来,再把最外层的布局改成ScrollView,再次运行,麻烦出现了:
这里写图片描述spa

天!咱们的ListView只剩下小小的一行了!试着滑动一下,发现滑动是没有问题的,就是只能显示一行。那咱们该怎么办呢?code

别着急,有一个简单的方法能够起死回生。咱们能够自定义一个ListView:xml

/**
 * 自定义ListView
 */
public class MyListView extends ListView {

    public MyListView(Context context) {
        super(context);
    }

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

    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,//右移运算符,至关于除于4
                MeasureSpec.AT_MOST);//测量模式取最大值
        super.onMeasure(widthMeasureSpec,heightMeasureSpec);//从新测量高度
    }
}

在这个ListView中咱们重写了onMeasure方法,而后从新定义heightMeasureSpec参数,它的大小取最大值的四分之一(通常的作法),测量模式取最大值,而后调用父类的构造方法从新传入heightMeasureSpec参数。这些步骤是为了保证ListView的高度不出现问题。完成后,咱们在布局文件中使用自定义的ListView:blog

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
    tools:context="com.lin.mr.mystudy.scrollview.TestActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />

        <com.lin.mr.mystudy.scrollview.MyListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </com.lin.mr.mystudy.scrollview.MyListView>

        <Button
            android:layout_margin="4dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮一" />

        <Button
            android:layout_margin="4dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮二" />

    </LinearLayout>

</ScrollView>

运行以后,发现问题解决了!ListView能够完整地显示,并且也能够滑动到头部和顶部的布局。图片

这里写图片描述

其实要想显示ListView的头部或者底部布局或者控件的话不必定要用ScrollView,咱们也能够将头部和底部做为一个总体的布局,即头布局或者脚布局,而后调用ListView的addHeaderView方法或者addFooterView方法就能够将它添加到ListView的头部或者底部了。

相关文章
相关标签/搜索