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的頭部或者底部了。

相關文章
相關標籤/搜索