最近由於項目功能原因,採用了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