android:ZoomPicker打破onTouchListener

我有一个使用内置缩放控件的webview,如下所示:

wv = new WebView(this); wv.getSettings().setBuiltInZoomControls(true); 

注意:这将激活两个主要function – 捏缩放和invokeZoomPicker()(后者只在视图上执行滑动操作时被调用,简单的触摸不会启用它)


我也希望发生触摸事件时发生的事情,使用以下内容

 wv.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { Log.i("touch", "touched!"); return false; } }); 

当WebView加载时,我点击屏幕,每当我与屏幕交互时,日志状态都会“触及”,如预期的那样。 然而,如果我做了一些将引发invokeZoomPicker()(捏缩放似乎不会导致这个问题,只要没有出现缩放小部件),onTouchListener停止响应我的水龙头(即使几秒钟后,当小部件从视图中消失)。

为了确保它是invokeZoomPicker(),我编辑了第二段代码,如下所示:

 wv.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { wv.invokeZoomPicker(); Log.i("touch", "touched!"); return false; } }); 

这个新的onTouch方法现在只触发一次(因此zoomwidget出现在视图上,几秒钟后消失),然后ontouch方法不会再被调用,直到视图重新加载 – 所以这是肯定的与invokeZoomPicker()/缩放小部件的问题

我是否错过了允许它们共存的一些重要的代码,或者我只需要select我可以不用的一个代码呢?

Solutions Collecting From Web of "android:ZoomPicker打破onTouchListener"

所以在我自己遇到同样的问题之后,我尝试了解一些这些答案是无济于事的。 现在的问题是,一旦用户调用滚动(而不是捏放大)(至less对我来说),WebView实例失去了它的OnTouchListener引用。 我怎么解决这个问题? 好…

Webview从ViewinheritancedispatchTouchEvent()。 dispatchTouchEvent调用onTouch()(这是不应该触发的function)

正如我之前所说,onTouch()没有被调用的原因是WebView实例的OnTouchListener由于某种原因被设置为null。 这可以通过在View的dispatchTouchEvent()方法中放置一个断点来看到

所以为了解决这个问题,我们像这样扩展WebView:

 import android.content.Context; import android.util.AttributeSet; import android.webkit.WebView; public class TouchWebView extends WebView { WebTouchListener wtl; public TouchWebView(Context context) { super(context); } public TouchWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public TouchWebView(Context context, AttributeSet attrs) { super(context, attrs); } public void resetTouchListener() { if(this.wtl == null) { this.wtl = new WebTouchListener(); } this.setOnTouchListener(wtl); } @Override public boolean dispatchTouchEvent(MotionEvent event) { this.resetTouchListener(); return super.dispatchTouchEvent(event); } } 

然后我们实现我们的OnTouchListener:

 import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.webkit.WebView; public class WebTouchListener implements OnTouchListener { @Override public boolean onTouch(View v, MotionEvent event) { WebView.HitTestResult hr = ((TouchWebView)v).getHitTestResult(); //Log.i(TAG, "getExtra = "+ hr.getExtra() + "\t\t Type=" + hr.getType()); if (event.getAction() == MotionEvent.ACTION_DOWN) { System.out.println(hr.getExtra() + " " + hr.getType()); } // TODO Auto-generated method stub return false; } } 

即使在缩放或滚动之后,OnTouch也会启动

我有同样的问题,但通过在扩展的WebView类中再次设置侦听器来设法解决它:

 public void invalidate() { super.invalidate(); setOnTouchListener(this); } 

不幸的是,现在我有相反的问题,缩放控件(加号/减号小部件)不再接收触摸事件。 至less在Android SDK 8级(Froyo 2.2)中,似乎有一个独立的OnTouchListener和缩放。

这听起来像是一个错误,但很想find一个解决方法。

尝试

 youWebView.getSettings().setBuiltInZoomControls(false); 

这对我有用。

一个肮脏的解决scheme是覆盖在您的网页视图顶部的一个不可见的视图,并在那里检测到触摸,你必须区分触摸是否消耗,或返回false通过触摸到底层的Web视图。

解决方法非常简单。 您必须创build一个自定义类,它扩展了像LinearLayout这样的ViewGroup子类之一。 然后重写onInterceptTouchEvent – 它将在ViewGroup的子onTouchEvent之前被调用。 将webview控件放入自定义的ViewGroup子类并不是很优雅,然后将其插入到活动的视图层次结构中 – 它需要的地方,但它工作。

 private class OwnedLayout extends LinearLayout { protected OwnedLayout(Context context, AttributeSet attrs) { super(context, attrs); } protected OwnedLayout(Context context) { super(context); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { //Put Your code here return super.onInterceptTouchEvent(ev); } } 

这是最接近我可以解决这个问题。 无论何时触摸,我都需要将input焦点设置到WebView。 我能做到的唯一方法就是扩展WebView并重写onTouchEvent函数。 即使在WebView中使用缩放后,该函数也会被调用。

 public class NewWebView extends WebView { public NewWebView(Context context) { super(context); } public NewWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public NewWebView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent ev) { boolean consumed = super.onTouchEvent(ev); if (isClickable()) if (ev.getAction() == MotionEvent.ACTION_DOWN) { if (!hasFocus()) requestFocus(); } return consumed; } 

不要忘记,如果使用XML来创build布局,则需要将“WebView”更改为完全限定的包名称.NewWebView(否则,如果尝试执行如下操作,将会遇到令人困惑的ClassCastException:

  webView = (NewWebView) findViewById(R.id.new_web_view); 

我认为有一些排他性,例如,一个500×500的networking视图,你放大到1000×1000,然后你触及它,现在应该报告什么位置?

但我真的需要让他们一起工作。

我有一个类似的问题,在我使用捏缩放之后, onTouch不会被调用。 受jpeskin答案的启发,这段代码为我工作(将其添加到扩展WebView的类中):

 @Override public boolean onTouchEvent(MotionEvent event) { boolean consumed = super.onTouchEvent(event); onTouch(this, event); return consumed; } 

更新:

 @Override public boolean onTouch(View v, MotionEvent event) { return touchListener.onTouch(v, event); } 

touchListener的types是android.view.View.OnTouchListener

我有与Stijn.V相同的缩放问题。 我在他的回答中使用了代码,但仍然有touchListener有时被设置为null的问题。 这是我的完整的webview类,在Android 4.0 – 4.3testing

 public class BookWebView extends WebView implements OnTouchListener { private OnTouchListener mTouchListener; public BookWebView(Context context) { super(context); } public BookWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public BookWebView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { boolean consumed = super.onTouchEvent(event); onTouch(this, event); return consumed; } @Override public boolean onTouch(View v, MotionEvent event) { return mTouchListener.onTouch(v, event); } @Override public void setOnTouchListener(OnTouchListener l) { super.setOnTouchListener(l); if(l != null){ mTouchListener = l; } } 

}

为了完整起见,touchEvent是如何在我的调用活动中初始化的

 bookWebview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mGestureDetector.onTouchEvent(event); } }); 

我遇到了同样的问题,我扩展了WebView并创build了自己的ontouchlistener来避免这个bug。 例如:公共类BookknowWebView扩展WebView {

 private GestureDetector gestureDetector; private OnTouchListener mListener; /** * @param context * @param attrs * @param defStyle */ public BookknowWebView(Context context) { super(context); } /** * @param context * @param attrs * @param defStyle */ public BookknowWebView(Context context, AttributeSet attrs) { super(context, attrs); } /** * @param context * @param attrs * @param defStyle */ public BookknowWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setBookknowOnTouchListener(OnTouchListener l){ mListener = l; } /* * @see android.webkit.WebView#onTouchEvent(android.view.MotionEvent) */ @Override public boolean onTouchEvent(MotionEvent ev) { mListener.onTouch(this, ev); return gestureDetector.onTouchEvent(ev) || super.onTouchEvent(ev); } public void setGestureDetector(GestureDetector gestureDetector) { this.gestureDetector = gestureDetector; } 

}

对我来说工作得很好。 只需使用onTouchEvent(MotionEvent事件)而不是onTouch(View v,MotionEvent事件)。 即使setBuiltInZoomControls设置为true。