ScrollView中嵌套ListView只显示一行的问题

来源:互联网 发布:abaqus软件 编辑:程序博客网 时间:2024/05/22 00:43

首先要明白为什么要这样做。   

     ScrollView可以滚动,Listview也可以滚动,那么为什么要在ScrollViewh中嵌套ListView呢?

    来个例子给大家观察一下

        大家仔细观察QQ界面的布局就会发现,红色框中的内容用List View做非常简单;但是整个黑色框中整体又是可以滑动的。这样就免不了在Scroll View中嵌套List View。当然你也可以不用ListView,直接把红色框中的内容一个个做出来,不过这样未免太麻烦了吧,而且难于管理,又有失我们程序员的水准,所以我们当然会选择嵌套了。但是问题来了嵌套使用的话会使List View的高度计算有误,导致只能显示ListView中的一行内容。

解决方案大致有一下几种

一、一行代码完美搞定这个小问题

    !!!重写ListView!!!    什么!要重写控件惊恐,略过略过......

一提起重写控件或者自定义控件,一些初学者就望而却步,认为很难很难,是大神才搞的骚操作。其实不然,自定义控件非常简单,而且有固定的套路(由于不是讲自定义控件这里就不详述了)。看下面的代码好像很难,其实前三个构造函数都是重写ListView构造函数,根本不用动手敲(IDE)会自动帮你完成。只是重写了onMeasure方法,而且就增加了一行代码

int measuredHeight = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
如果无法解决你的问题,多半是下一行代码需要替换一个变量,被你马虎了。

public class MyList extends ListView{    public MyList(Context context) {        super(context);    }    public MyList(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyList(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int measuredHeight = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);//只写了这一句就搞定了        super.onMeasure(widthMeasureSpec, measuredHeight);//这里需要将第二个参数改为我们测量好的measureHeight    }}


然后在xml文件中引用ListView的地方改为我们自定义的MyList就可以了(注意:引用自定义控件时一定要加上完整的包名)

就像这样


            <com.example.a57278.school.MyList                android:id="@+id/list_view"                android:layout_width="match_parent"                android:layout_height="match_parent">            </com.example.a57278.school.MyList>

结果

怎么样,完美解决问题,是不是很简单呢!



二、手动设置ListView的高度

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.a57278.school.MainActivity">    <ScrollView        android:layout_width="match_parent"        android:layout_height="match_parent">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent">            <ListView                android:id="@+id/list_view"                android:layout_width="match_parent"                android:layout_height="100dp">            </ListView>        </LinearLayout>    </ScrollView>    </android.support.constraint.ConstraintLayout>


这个解决办法非常完美,但也特别鸡肋。因为在开发过程中是很忌讳直接指定尺寸的,这样会导致不同分辨率,不同尺寸屏幕上显示的目标尺寸不一致,甚至导致界面十分混乱。


三、用一个ListView代替ScrollView

思路:将ScrollView中的其他部分也作为一项显示在ListView中。

只需为ScrollView中的各个部分分别建立布局


在重写BaseAdapter中的getView方法时只需要

    @Override    public View getView(int position, View convertView, ViewGroup parent) {        TrendViewHolder holder = null;        if(convertView == null) {            holder = new TrendViewHolder();            if(position == 0) {                convertView = mInflater.inflate(R.layout.list_layout_top,null);            } else if(position == 4){                convertView = mInflater.inflate(R.layout.list_layout_bottom,null);            } else {                convertView = mInflater.inflate(R.layout.list_item,null);            }            holder.iconView = (ImageView)convertView.findViewById(R.id.list_icon);            holder.titleView = (TextView)convertView.findViewById(R.id.list_title);            holder.arrowView = (ImageView)convertView.findViewById(R.id.list_arrow);            convertView.setTag(holder);        } else {            holder = (TrendViewHolder) convertView.getTag();        }        holder.iconView.setImageBitmap(mData.get(position).getIcon());        holder.titleView.setText(mData.get(position).getTitle());        holder.arrowView.setImageBitmap(mData.get(position).getArrow());        return convertView;    }
这样根据不同的position为不同的item定制不同的布局文件就可以了。不过数据源的适配又是个大问题,因为顶部,中部和底部的数据源格式不一致(如果一致的话又何必在ScrollView中嵌套ListView)呢?


四、使用LinearLayout或RelativeLayout代替List View,将每个item的布局都写出来。分别为每个布局添加点击事件,这里就不演示了(太麻烦尴尬)。


五、动态计算ListView的高度

    public 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);               // 计算子项View 的宽高               listItem.measure(0, 0);                // 统计所有子项的总高度               totalHeight += listItem.getMeasuredHeight();            }              ViewGroup.LayoutParams params = listView.getLayoutParams();           params.height = totalHeight+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));           // listView.getDividerHeight()获取子项间分隔符占用的高度           // params.height最后得到整个ListView完整显示需要的高度           listView.setLayoutParams(params);       }  

代码也不难,将所有的iem高度加起来,然后再加上所有分割线的高度,将其设置为整个Listview的高度就行了。






六、设置Scroll View的属性

    <ScrollView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:fillViewport="true">    </ScrollView>

只要设置

android:fillViewport="true"就可以了。

看其他人的帖子里面有这样写的。试了一下并不能解决我的问题。在这里提一下,万一能解决你们的 问题呢吐舌头



大家看到代码中有一些看不懂的标签或这尖括号之类的请自行略过(本来想把重要的代码高亮标出来,结果编辑器不太智能,把标签都显示出来了),万望见谅。

阅读全文
0 0
原创粉丝点击