最近在开发者中碰到一个头疼的问题,发现webview嵌套在scrollview中后,webview的锚点定位功能失效,经过查阅一番折腾后发现还是没找到很好的方法解决,于是想了另外一种方法,
思路:通过计算目标点在scrollview的位置top,调用scrollTo(0,top)
方法定位
实现:页面布局是这样的
<ScrollView>
<View>
</View>
<WebView>
<div id="anchor"></div>
</WebView>
</ScrollView>
so top=height(View)+height(div)
首先View到顶部的距离好说,view.getTop即可,代码如下:
/**
* 测量商品信息导航栏离顶端高度
*/
private void getTopForNav() {
ViewTreeObserver vto = rg_info_nav.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
mHeight = rg_info_nav.getTop();
return true;
}
});
}
问题来了,怎么计算webview中某个节点离webview顶端的距离呢,没错,就是通过js计算,然后通过alert()弹出,在android中就可以拿到了,代码如下:
js:
function d_desc(){
var desc = document.getElementById("desc");
var topa = desc.offsetTop;
alert(topa);
}
android:
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
result.cancel();
if (!TextUtils.isEmpty(message)) {
try {
int top = Integer.parseInt(message);
mStickyScrollView.scrollTo(0, mHeight + (int) (top * mDensity));
} catch (Exception e) {
}
}
return true;
}
});
//mDensity=getResources().getDisplayMetrics().density;屏幕密度
在需要定位的地方调用即可:
mWebView.loadUrl("javascript: d_desc()");
疑点
top * mDensity
:通过js获取到的top值就是px,mHeigh获取到的也是px,但是如果调用scrollTo(mHeigh+top)位置会不对,必须写成scrollTo(mHeigh+top*mDensity),此问题暂时在此mark,待弄清楚后再来解释