«

解决ScollView、GridView及Expandlistview嵌套ListView显示不全问题

时间:2024-3-2 19:21     作者:韩俊     分类: Android


大多数时候,我们用ListView来加载数据的页面不需要在ListView的外面再套上一个ScollView,因为ListView本身可以滚动显示数据。有时我们页面中除要用ListView显示列表数据之外还要显示其它数据,这时候就需要在整个页面最个层套上一个Scollview,否则显示就可能出现问题(比如在ListView上面已经有很多其它数据,显示在手机上直接导致ListView看不见了,这时就要在整个屏幕布局加ScollView实现滑动界面),用过ScollView嵌套ListView的朋友都知道,在不做任务处理的情况下,ListView的数据只能显示一行多一点点,其它的就看不到了,这个问题怎么解决呢?通常我们可以有下面两种方式:


1,计算高度:(自定义工具类)

import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ListView;

public class ListViewUtils {

    /*******************************************************************/
    //TODO 解决ScollView、GridView及Expandlistview嵌套ListView显示不全问题
    /*******************************************************************/
    private static int totalHeight = 0;

    public static void setListViewHeight(ListView listView){
        /*得到适配器*/
        Adapter adapter = listView.getAdapter();

        /*遍历控件*/
        for (int i = 0; i < adapter .getCount(); i++) {
            View view = adapter .getView(i, null, listView);
            /*测量一下子控件的高度*/
            view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            totalHeight+=view.getMeasuredHeight();
        }

        /*控件之间的间隙*/
        totalHeight+=listView.getDividerHeight()*(listView.getCount()-1);

        /*2、赋值给ListView的LayoutParams对象*/
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight;
        listView.setLayoutParams(params);

    }
}


这里有一点要注意:我每次调用的时候都会产生在listItem.measure(0,0)报空指针异常。我debug 发现listItem 并不是为空啊,为啥会报错。在经过一番查找之后。我发现原来是自己item的布局用了RelativeLayout 把他换为LinearLayout 就好了。究其原因,原来是 Linearlayout重写了onmeasure方法,其他的布局文件没有重写onmeasure,所以在调用listItem.measure(0, 0); 会报空指针异常,如果想用这个东东,就必须用linearlayout布局喽


2,重写ListView的onMeasure:

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;

public class WholeListView extends ListView {

    public WholeListView (Context context) {
    super(context);
    }

    public WholeListView (Context context, AttributeSet attrs) {
    super(context, attrs);
    }

    public WholeListView (Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
} 


这里解释下onMeasure方法:

onMeasure方法是测量view和它的内容,决定measured width和measured height的这个方法由 measure(int, int)方法唤起,子类可以覆写onMeasure来提供更加准确和有效的测量。其中两个输入参数:widthMeasureSpec,heightMeasureSpec,分别是parent提出的水平和垂直的空间要求。这两个要求是按照View.MeasureSpec类来进行编码的。

参见View.MeasureSpec这个类的说明:这个类包装了从parent传递下来的布局要求,传递给这个child。每一个MeasureSpec代表了对宽度或者高度的一个要求。每一个MeasureSpec有一个尺寸(size)和一个模式(mode)构成。MeasureSpecs这个类提供了把一个的元组包装进一个int型的方法,从而减少对象分配。当然也提供了逆向的解析方法,从int值中解出size和mode。

标签: android

热门推荐