我正在Android WebView中显示一个网页。需要缩放页面以适合WebView的可用宽度。
HTML(宽度550只是一个例子,可能会改变):
<html>
<head>
<meta name="viewport" content="width=550">
...
爪哇:
mWebView = (WebView)findViewById(R.id.webView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setHorizontalScrollBarEnabled(false);
mWebView.setVerticalScrollBarEnabled(false);
mWebView.requestFocus(View.FOCUS_DOWN);
mWebView.getSettings().setLoadWithOverviewMode(true); // required for scaling
mWebView.getSettings().setUseWideViewPort(true); // required for scaling
mWebView.loadUrl(someUrl);
除了一个问题之外,这样可以正常工作:双标签触发概览模式和默认比例之间的切换 有没有办法禁用此功能?
顺便说一句:我无法计算代码中的比例,因为加载的页面可能有不同的大小,我事先并不知道。我也检查了WebView的源代码,但没有看到任何内容,我可以覆盖或更改。
答案 0 :(得分:1)
您可以编写自己的WebView实现实现OnGestureListener:
public class MyWebView extends WebView implements OnGestureListener
Inside声明一个GestureDetector:
private GestureDetector gestureDetector;
实现一个initWebView()方法并在构造函数中调用它,如下所示:
// Best you do this for every WebViewConstructor:
public AppWebView(Context context) {
super(context);
initWebView(); }
private void initWebView(){
gestureDetector = new GestureDetector(getContext(), this);
// Do any other customizations for your webview if you like.
}
现在实现OnGestureListener中的方法,并在双击事件中返回true:
public boolean onSingleTapConfirmed(MotionEvent e) {
return false; //Nothing
}
public boolean onDoubleTap(MotionEvent e) {
return true; //Nothing
}
public boolean onDoubleTapEvent(MotionEvent e) {
return true; //Nothing
}
public boolean onDown(MotionEvent e) {
return false; //Nothing
}
public void onShowPress(MotionEvent e) {
//Nothing
}
public boolean onSingleTapUp(MotionEvent e) {
return false; //Nothing
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false; //Nothing
}
public void onLongPress(MotionEvent e) {
//Nothing
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false; //Nothing
}
最后覆盖webview的OnTouchEvent并让它将事件传递给手势检测器,如下所示:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) return true;
return super.onTouchEvent(event);
}
这一般工作得很好但是这个解决方案有一个基本缺陷:一些未被识别为DoubleTap事件的事件可能会导致您的webview缩放。
我仍在为此制定解决方案,并将在此处发布我的进展: WebView getting rid of double tap zoom.
答案 1 :(得分:0)
总的来说,更改已知的API并不是一种好习惯。你应该找到一种不同的方法,也许longClick
。
无论如何,请看this similar question。
答案 2 :(得分:0)
如果可能,请替换html中的静态元标记:
<script>
var meta = document.createElement("meta");
meta.setAttribute('name','viewport');
meta.setAttribute('content','width=device-width, user-scalable=no');
document.getElementsByTagName('head')[0].appendChild(meta);
</script>
此外,您可以使用一个漂亮的脚本:FastClick
它不会等待点击事件,所以它更快。
<script type="application/javascript" src="fastclick.js"></script>
<script language="javascript">
window.addEventListener('load', function() {
FastClick.attach(document.body);
}, false);
</script>
然后为您的手势检测器设置双击侦听器。 (在自定义WebView中)
gestureDetector.setOnDoubleTapListener(new OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed( MotionEvent e ) {
return false;
}
@Override
public boolean onDoubleTapEvent( MotionEvent e ) {
return true;
}
@Override
public boolean onDoubleTap( MotionEvent e ) {
return true;
}
});
重写onTouchEvent方法(在自定义WebView中):
@Override
public boolean onTouchEvent( MotionEvent event ) {
boolean gestureHandled = gestureDetector.onTouchEvent(event);
int actionMask = event.getActionMasked() & MotionEvent.ACTION_MASK;
int index = ( event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pointId = event.getPointerId(index);
// ignore move events
if (actionMask == MotionEvent.ACTION_MOVE) {
return super.onTouchEvent(event);
}
// cancel detected double taps
if (gestureDetector.onTouchEvent(event)) {
event.setAction(MotionEvent.ACTION_CANCEL);
super.onTouchEvent(event);
return true;
}
// if you want to ignore multi touch events/taps
if (pointId != 0) {
System.out.println("KEY multiple points detected");
return true;
}
// use single taps
if (event.getAction() == MotionEvent.ACTION_UP) {
event.setAction(MotionEvent.ACTION_CANCEL);
super.onTouchEvent(event);
event.setAction(MotionEvent.ACTION_DOWN);
super.onTouchEvent(event);
event.setAction(MotionEvent.ACTION_UP);
return true;
}
return super.onTouchEvent(event);
}