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

来源:互联网 发布:php nginx 403 编辑:程序博客网 时间:2024/05/16 03:45

最近由于项目功能原因,采用了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

1 0
原创粉丝点击