ScrollView中嵌套ListView

ScrollView嵌套ListView

在开发中,我们常会用到在一个可以滑动的界面中添加ListView(不止一个,否则直接使用一个ListView或
ScrollView就可以了)的情况,这就是ScrollView嵌套ListView。

这里写图片描述

就像上边一样的布局:整体是一个可以滑动的ScrollView,中间有三个ListView,而且每个ListView的item数量不一定。

注意:

①:若没有给ListView加id,在预览视图中是看不到ListView的;

②:如果给每个ListView都设置固定高度,则会出现整体ScrollView可以滑动,而每个ListView不能滑动(并不是完全不能滑动,若一个手指按住屏幕不动,另一个手指滑动ListView,是可以滑动的),这样就会出现ListView高度固定导致item不能全部显示的问题。

需求的实现思路:

  • 布局设置:根据需求,每个ListView的高度设置为自适应
<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.example.com.MainActivity" >
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="第一个ListView" 
            android:textColor="#f00"
            android:textSize="20sp"/>
        <ListView 
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </ListView>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="第一个ListView" 
            android:textColor="#f00"
            android:textSize="20sp"/>
        <ListView 
            android:id="@+id/listView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </ListView>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="第一个ListView" 
            android:textColor="#f00"
            android:textSize="20sp"/>
        <ListView 
            android:id="@+id/listView3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </ListView>
    </LinearLayout>
</ScrollView>
  • 定义Adapter
public class ListViewAdapter extends BaseAdapter{

    Context context;

    List<ItemEntity> items=null;

    public ListViewAdapter(Context context,List<ItemEntity> entities) {
        super();
        this.context=context;
        this.items=entities;
    }

    static class ViewHolder{
        private TextView name;
        private TextView sexes;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null){
            convertView=LayoutInflater.from(context).inflate(R.layout.list_view_adapter_layout,null);
            viewHolder=new ViewHolder();
            viewHolder.name=(TextView)convertView.findViewById(R.id.name);
            viewHolder.sexes=(TextView)convertView.findViewById(R.id.sexes);
            convertView.setTag(viewHolder);
        }else{
            viewHolder=(ViewHolder)convertView.getTag();
        }
        viewHolder.name.setText(items.get(position).getName());
        viewHolder.sexes.setText(items.get(position).getSexes());
        return convertView;
    }
}
  • 子Item的布局(在ScrollView嵌套ListView的问题中,Item的布局必须是LinearLayout,只有它有onMeasure()方法)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    <TextView 
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="8dp"/>
    <TextView 
        android:id="@+id/sexes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|right"
        android:layout_marginRight="8dp"/>
</LinearLayout>
  • 存放数据的实体类
package com.example.com;

public class ItemEntity {
    private String name;
    private String sexes;

    public ItemEntity() {
        super();
    }
    public ItemEntity(String name, String sexes) {
        super();
        this.name = name;
        this.sexes = sexes;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSexes() {
        return sexes;
    }
    public void setSexes(String sexes) {
        this.sexes = sexes;
    }
}
  • Activity实现,setListViewHeightBasedOnChildren(ListView listView)方法计算整个ListView的高度,然后赋值给ListView,此方法应该在setAdapter()之后调用。
public class MainActivity extends Activity {

    private List<ItemEntity> items=null;

    private ListViewAdapter adapter;

    private ListView listView1;

    private ListView listView2;

    private ListView listView3;

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

    private void init() {
        items=new ArrayList<ItemEntity>();
        adapter=new ListViewAdapter(getApplication(), items);

        listView1=(ListView)findViewById(R.id.listView1);
        listView2=(ListView)findViewById(R.id.listView2);
        listView3=(ListView)findViewById(R.id.listView3);

        items.add(new ItemEntity("德瑪","男"));
        items.add(new ItemEntity("男槍","男"));
        items.add(new ItemEntity("火女","女"));
        items.add(new ItemEntity("奧巴馬","男"));
        items.add(new ItemEntity("武器大師","男"));
        items.add(new ItemEntity("瑞茲","男"));
        items.add(new ItemEntity("女槍","女"));
        items.add(new ItemEntity("石頭人","男"));

        listView1.setAdapter(adapter);
        listView2.setAdapter(adapter);
        listView3.setAdapter(adapter);
        setListViewHeightBasedOnChildren(listView1);
        setListViewHeightBasedOnChildren(listView2);
        setListViewHeightBasedOnChildren(listView3);
    }

    public static void setListViewHeightBasedOnChildren(ListView listView) {  
        // 获取ListView对应的Adapter  
        ListAdapter listAdapter = listView.getAdapter();  
        if(listAdapter == null) {  
            return;  
        }  
        int totalHeight = 0;  
        for(int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目  
            View listItem = listAdapter.getView(i, null, listView);  
            listItem.measure(0, 0); // 计算子项View 的宽高  
            totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度  
        }  
        ViewGroup.LayoutParams params = listView.getLayoutParams();  
        params.height = totalHeight  
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));  
        // listView.getDividerHeight()获取子项间分隔符占用的高度  
        // params.height最后得到整个ListView完整显示需要的高度  
        listView.setLayoutParams(params);  
    }  
}

在这个Demo中,三个ListView的数据是写死的,在实际应用中,可以加载不同数量不同形式的数据。

另外一种情况

上边说过,ListView的Item数量是不固定的,那么如果这个ListView没有数据,难道只显示一个标题,然后下边的ListView部分省略,下边接着一个标题+ListView吗??

这样显然是不合理的,我们应该在ListView没有数据的时候显示提示语(或者直接省略这个标题和ListVew)。

这里有一个在ListView没有数据的时候显示提示语的例子。
(参考http://www.cnblogs.com/mengdd/archive/2013/08/28/3287662.html)

<!--
    The frame layout is here since we will be showing either
    the empty view or the list view.
    -->

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >

        <!--
             Here is the list. Since we are using a ListActivity, we
             have to call it "@android:id/list" so ListActivity will
             find it
        -->

        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:drawSelectorOnTop="false" />

        <!-- Here is the view to show if the list is emtpy -->

        <TextView
            android:id="@android:id/empty"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="No items."
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </FrameLayout>

android:id=”@android:id/empty”
这个属性值的作用就是,当ListView关联的Adapter中数据为空时,就显示这个TextView。
而这个ListView中有数据显示时,这个TextView是不可见的。

以上,就是ScrollView嵌套ListView的整个实现过程,如有问题,欢迎大家指出!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值