ScrollView遇上ListView

ScrollView遇上ListView


ScrollView 和 ListView是我们Android开发中常用的控件,可是由于都有对于滚动时间的处理,当ScrollView里面嵌套包含ListView的布局时,就会出现布局错误,ListView 不能完整显示。

对于ScrollView,我们知道其实它是继承自FrameLayout布局,所以ScrollView内部只能包含一个子节点,通常情况下是垂直方向上的线性布局!

Layout container for a view hierarchy that can be scrolled by the user, allowing it to be larger than the physical display. A ScrollView is a FrameLayout, meaning you should place one child in it containing the entire contents to scroll; this child may itself be a layout manager with a complex hierarchy of objects. A child that is often used is a LinearLayout in a vertical orientation, presenting a vertical array of top-level items that the user can scroll through.

You should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.

The TextView class also takes care of its own scrolling, so does not require a ScrollView, but using the two together is possible to achieve the effect of a text view within a larger container.

错误实例

<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>

解决方案


1.整个布局使用ListView

整个布局使用ListView,然后通过addHeaderView()和addFooterView()方法添加额外的布局元素!

  • activity_main.xml
<RelativeLayout 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"
     >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" >

    </ListView>

</RelativeLayout>
  • listview_header.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

     <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:src="@drawable/coverblur" >
    </ImageView>


</RelativeLayout>
  • listview_footer.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:src="@drawable/cover" >
    </ImageView>

</RelativeLayout>
  • MainActivity.java
package com.example.scrollviewlistview;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.os.Build;

public class MainActivity extends Activity {
    private ListView listView;
    private ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView=(ListView)this.findViewById(R.id.listView1);
        adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getData());
        listView.setAdapter(adapter);

        //解决ScrollView和ListView冲突的问题
        /*
         * 1.整个布局使用ListView
         * 2.通过ListView.addHeaderView添加头部视图
         * 3.通过ListView.addFooterView添加尾部视图已实现更多元素的布局和List的搭配
         * 
         */
        LayoutInflater inflater=LayoutInflater.from(this);
        View headerView=inflater.inflate(R.layout.listview_header, listView, false);
        listView.addHeaderView(headerView);
        View footerView=inflater.inflate(R.layout.listview_footer, listView, false);
        listView.addFooterView(footerView);



    }


    private List<String> getData() {
        List<String> stringList=new ArrayList<String>();
        for(int i=0;i<15;i++){
            stringList.add("listItem"+i);
        }
        return stringList;
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }



}
  • 运行结果

这里写图片描述


2. 计算ListView的高度

在ScrollView中嵌套包含ListView的布局,ListView height还设置为match_parent,但是在运行时间ListView却只会显示大概一个Item的宽度。可以通过显示设置ListView height的方式解决。在代码中,得到Adapter中数据的个数,计算每个item的高度,得到ListView的总高度,设置高度,即可完成!

3.分发滚动事件

通过复写在activity中dispatchTouchEvent(MotionEvent ev)方法,分发滚动时间给内部的ListView!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值