Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 安卓:ZoomPicker打破了传统的监听模式_Android_Webview_Zooming_Ontouchlistener - Fatal编程技术网

Android 安卓:ZoomPicker打破了传统的监听模式

Android 安卓:ZoomPicker打破了传统的监听模式,android,webview,zooming,ontouchlistener,Android,Webview,Zooming,Ontouchlistener,我有一个webview,它使用内置的缩放控件,如下所示: wv = new WebView(this); wv.getSettings().setBuiltInZoomControls(true); wv.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { wv.invokeZoomPicker(); L

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

wv = new WebView(this);
wv.getSettings().setBuiltInZoomControls(true);
wv.setOnTouchListener(new View.OnTouchListener() {  
    public boolean onTouch(View v, MotionEvent event) {
        wv.invokeZoomPicker();
        Log.i("touch", "touched!");
        return false;
    }
});
注意:这将激活两个主要功能-pinch to zoom和invokeZoomPicker()(后者仅在视图上执行滑动操作时调用,简单的触摸无法启用)


我还希望在触摸事件发生时发生以下情况

wv.setOnTouchListener(new View.OnTouchListener() {  
    public boolean onTouch(View v, MotionEvent event) {
        Log.i("touch", "touched!");
        return false;
    }
});
当WebView加载时,我点击屏幕,每次我与屏幕交互时,日志都会显示“触动”,正如预期的那样。但是,如果我做了一些会触发invokeZoomPicker()的操作(只要zoom小部件不出现,收缩到缩放似乎不会导致此问题),onTouchListener将停止响应我的点击(即使在几秒钟后,当小部件从视图中消失时)

为了确保它是invokeZoomPicker(),我对代码的第二段进行了如下编辑:

wv = new WebView(this);
wv.getSettings().setBuiltInZoomControls(true);
wv.setOnTouchListener(new View.OnTouchListener() {  
    public boolean onTouch(View v, MotionEvent event) {
        wv.invokeZoomPicker();
        Log.i("touch", "touched!");
        return false;
    }
});
这个新的onTouch方法现在只触发一次(结果zoomwidget出现在视图上,几秒钟后消失),然后onTouch方法在视图重新加载之前不会再次被调用,因此invokeZoomPicker()/Zoom小部件肯定有问题


我是否错过了一些允许它们共存的关键代码,还是我只需要选择一个我可以不使用的代码?

这是我最接近于解决这个问题的方法。我需要在触摸WebView时将输入焦点设置为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创建布局,则需要将“WebView”更改为完全限定的packagename.NewWebView(否则,如果尝试执行以下操作,会出现令人困惑的ClassCastException):

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

我也遇到了同样的问题,但通过在扩展WebView类中再次设置侦听器,我成功地解决了这个问题:

public void invalidate() {
    super.invalidate();
    setOnTouchListener(this);
}
不幸的是,现在我遇到了相反的问题,缩放控件(加减小部件)不再接收触摸事件。至少在Android SDK级别8(Froyo 2.2)中,OnTouchListener和zoom之间似乎存在某种排他性


对我来说这听起来像一个bug,但我很想找到一个解决办法。

我认为有一些排他性,例如,对于500x500的web视图,您将其放大到1000x1000,然后您触及它,现在它应该报告什么位置


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

一个肮脏的解决方案是在web视图顶部覆盖一个不可见的视图,并在那里检测触摸,您必须区分触摸是否被使用,或者返回false以将触摸传递到基础web视图。

解决方法非常简单。 您必须创建一个自定义类,该类扩展了一个ViewGroup子类,如LinearLayout。然后重写onInterceptTouchEvent-它将在ViewGroup子级的onTouchEvent之前调用。将webview控件放入自定义ViewGroup子类中,然后将其插入到活动的视图层次结构中,这样做并不十分优雅红色,但是-它有效。


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

更新:

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

touchListener
属于android.view.view.OnTouchListener类型。我与Stijn.V有相同的缩放问题。我在他的回答中使用了代码,但touchListener有时被设置为null时仍然存在问题。这是我的完整webview类,在android 4.0-4.3上测试

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并创建了自己的ontouchlistener以避免此错误。例如: 公共类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;
}   

}

因此,在我自己遇到同样的问题后,我试图理解其中的一些答案,但没有任何效果。目前的问题是,一旦用户调用scroll(而不是pinch zoom)(至少对我来说…),WebView实例将丢失其OnTouchListener引用。我是如何解决的?嗯

Webview从视图继承dispatchTouchEvent()。 dispatchTouchEvent调用onTouch()

正如我前面所说,onTouch()没有被调用的原因是WebView实例的OnTouchListener由于某种原因被设置为null

为了解决这个问题,我们对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现在即使在缩放或滚动后也会启动

对我来说效果非常好。只需使用onTouchEvent(MotionEvent事件)而不是OnTouch(View v,MotionEvent事件)。即使SetBuilTinZoomControl设置为true也能工作。

我也遇到了同样的问题。您是否找到了解决方案?不幸的是,我还没有找到解决方案。很抱歉,我没有更早地找到它,但我终于有机会测试此代码,不幸的是,此方法无法再次工作。您的代码没有在中为我编译一个扩展WebView的类——它说onTouch方法未定义。您自己在WebView子类中实现了onTouch方法吗?如果是这样,您的示例将更清晰,用注释代替onTouch()调用。我已经检查了它,我确实有一个
onTouch()扩展WebView类中的
方法,因此类
实现了OnTouchListener
。这对我来说非常有效。我只是制作了一个
,并将其放置在
内部的
上。然后我将
视图的
设置为OnTouchListener
,并使其返回
false
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;
    }


}