详解:scrollview嵌套listview,而listview的item中是webview,导致listview不能在scrollview完全伸展开的问题

最近由于项目功能原因,采用了scrollview嵌套listview的方法,但是listview中的item又包含webview,导致了一些高度计算错误,listview不能完全伸展的问题:
第一种:普通的item(不包含特殊的不能明确知道高度的view的),计算listview的高度比较简单,重写listview的onMeasure()方法即可:
具体:

public class NoScrollListview extends ListView{

    public NoScrollListview(Context context, AttributeSet attrs) {  
        super(context, attrs);
        setVerticalScrollBarEnabled(false);
    }


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

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

    public void setIsWebView(boolean isWebView){
        this.isWebView=isWebView;
    }
    /** 
     * 设置不滚动 
     */
     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >>2,
                    MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec); 
    }
}

当然网上还有大神总结了四种方式去获取高度,并总结了四种方式的优缺点,这里我就不细说了,下面是链接:
四种方式获取scrollview中listview的高度
**

第二种:就是我遇到的问题:scrollview嵌套了listview,但是listview的每一个item是webview,这样上述的四种方案都会失效,因为webview加载数据有两种特点:

一:加载数据是异步的(这就导致咱们重构的onMeasure()方法没有用!);
二:webview的高度计算分为两种:如果是网络上的(也就是url中的)数据,webview可以准确计算高度,但是如果是本地的带有html参数的数据,这高度就不太准确;

由于上述的两种情况就导致,所有的关于listview的高度计算的方式都失去效果,如果webview的setWebViewClient(android.webkit.WebViewClient)(这个方法已经过时,并且计算高度不太准确)和setWebChromeClient(android.webkit.WebChromeClient)(这个主要是针对url上的数据进行设计的)失去作用就没有其他方式解决了吗?
我查了很多webview的相关资料终于发现一个问题:大家一般都走进了误区,认为上述两种方式执行完就是webview的内容加载完成,的确,这两种方式走完之后内容是已经加载完毕,但加载完毕和绘制完毕时不同的两种概念,只有的绘制完毕后,他的高度才是真正的固定,而内容加载完毕,他的高度有可能还没有设置成功!
所以我重写了webview的方法,自定义了一个接口,在他重绘完成后才响应

public class XWebView extends WebView {
    public Context context;

    public interface PlayFinish{
        void After();
    }
    PlayFinish df;
    public void setDf(PlayFinish playFinish) {
        this.df = playFinish;
    }
    public XWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context=context;
        setBackgroundColor(0);
        setVerticalScrollBarEnabled(false);

    }
    public XWebView(Context context) {
        super(context);
        this.context=context;
    }
    //onDraw表示显示完毕
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        df.After();
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        invalidate();
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    /**
     * 设置不能点击
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        return false;
    }


}

也就是上述代码中的After()方法,每当他重绘成功我就调用这个方式获取item的真是高度,由于我的webview实在listview中所以,响应事件在adapter,需要在定义一个回调接口,用来在activity中获取真实的高度,这个比较简单也就是在主页面写一个hashmap用来存储计算的webview的高度即可!
至此,我的关于scrollview嵌套listview,listview嵌套webview的多重计算高度的问题算是解决了,如果有朋友有更好的解决方案,可以相互讨论一下!

转载时请命名出处:http://blog.csdn.net/u010785186/article/details/50828785

你可能感兴趣的:(错误笔记)