您的位置:首页 > 移动开发

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

2016-03-08 17:17 766 查看
最近由于项目功能原因,采用了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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息