詳解: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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章