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

所属分类: 软件编程 / Android 阅读数: 52
收藏 0 赞 0 分享

ScrollView和ListView这两个控件想必大家都不会陌生,但是这两者嵌套使用的时候就会出现麻烦。比如,我们如果想在ListView下面添加其他的布局或者控件,然后想让它们作为一个整体都可以滑动的话,最常想到的就是用一个ScrollView把它们包裹起来。想法似乎很美好,但是现实就有点残酷了。我们可以写一个小例子体验一下。

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

<?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,而没有自己去自定义。

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的头部或者底部添加一些控件,然后让它们整体都可以滑动呢?我们可以先这样试试:

<?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,再次运行,麻烦出现了:

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

别着急,有一个简单的方法可以起死回生。我们可以自定义一个ListView:

/**
 * 自定义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:

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

Android网络编程之获取网络上的Json数据实例

这篇文章主要介绍了Android网络编程之获取网络上的Json数据实例,本文用完整的代码实例讲解了在Android中读取网络中Json数据的方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中的windowSoftInputMode属性详解

这篇文章主要介绍了Android中的windowSoftInputMode属性详解,本文对windowSoftInputMode的9个属性做了详细总结,需要的朋友可以参考下
收藏 0 赞 0 分享

Android网络编程之UDP通信模型实例

这篇文章主要介绍了Android网络编程之UDP通信模型实例,本文给出了服务端代码和客户端代码,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中使用ListView实现漂亮的表格效果

这篇文章主要介绍了Android中使用ListView实现漂亮的表格效果,本文用详细的代码实例创建了一个股票行情表格,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中刷新界面的二种方法

这篇文章主要介绍了Android中刷新界面的二种方法,本文使用Handler、postInvalidate两种方法实现界面刷新,需要的朋友可以参考下
收藏 0 赞 0 分享

Android SDK三种更新失败及其解决方法

这篇文章主要介绍了Android SDK三种更新失败及其解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(一)

Android3.0(API level 11)开始,Android设备不再需要专门的菜单键。随着这种变化,Android app应该取消对传统6项菜单的依赖。取而代之的是提供anction bar来提供基本的用户功能
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(二)

这次将继续上一篇文章没有讲完的Menu的学习,上下文菜单(Context menu)和弹出菜单(Popup menu)
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(三)

今天继续昨天没有讲完的Menu的学习,主要是Popup Menu的学习,需要的朋友可以参考下
收藏 0 赞 0 分享

Android显示网络图片实例

这篇文章主要介绍了Android显示网络图片的方法,以实例形式展示了Android程序显示网络图片的方法,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多