我想知道什么时候用户点击网络视图,但不是在一个超链接。在单击时,我想显示/隐藏一个包含 webview 的活动视图。有什么建议吗?
我看了看这个,我发现一个 WebView似乎不发送点击事件到一个 OnClickListener。如果有人能证明我错了或者告诉我为什么,我会很感兴趣的。
WebView
OnClickListener
我所发现的是,一个 WebView将发送触摸事件到一个 OnTouchListener。它确实有自己的 onTouchEvent方法,但是我似乎只能用这个方法得到 MotionEvent.ACTION_MOVE。
OnTouchListener
onTouchEvent
MotionEvent.ACTION_MOVE
因此,既然我们可以在已注册的触摸事件监听器上获取事件,那么剩下的唯一问题就是当用户单击 URL 时,如何规避您想要执行的任何触摸操作。
这可以通过一些花哨的 Handler步骤来实现,即发送触摸延迟消息,然后如果触摸是由用户单击 URL 引起的,则删除这些触摸消息。
Handler
这里有一个例子:
public class WebViewClicker extends Activity implements OnTouchListener, Handler.Callback { private static final int CLICK_ON_WEBVIEW = 1; private static final int CLICK_ON_URL = 2; private final Handler handler = new Handler(this); private WebView webView; private WebViewClient client; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.web_view_clicker); webView = (WebView)findViewById(R.id.web); webView.setOnTouchListener(this); client = new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { handler.sendEmptyMessage(CLICK_ON_URL); return false; } }; webView.setWebViewClient(client); webView.setVerticalScrollBarEnabled(false); webView.loadUrl("http://www.example.com"); } @Override public boolean onTouch(View v, MotionEvent event) { if (v.getId() == R.id.web && event.getAction() == MotionEvent.ACTION_DOWN){ handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 500); } return false; } @Override public boolean handleMessage(Message msg) { if (msg.what == CLICK_ON_URL){ handler.removeMessages(CLICK_ON_WEBVIEW); return true; } if (msg.what == CLICK_ON_WEBVIEW){ Toast.makeText(this, "WebView clicked", Toast.LENGTH_SHORT).show(); return true; } return false; } }
您可以通过 OnTouchListener 实现 OnClickListener:
webView.setOnTouchListener(new View.OnTouchListener() { public final static int FINGER_RELEASED = 0; public final static int FINGER_TOUCHED = 1; public final static int FINGER_DRAGGING = 2; public final static int FINGER_UNDEFINED = 3; private int fingerState = FINGER_RELEASED; @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: if (fingerState == FINGER_RELEASED) fingerState = FINGER_TOUCHED; else fingerState = FINGER_UNDEFINED; break; case MotionEvent.ACTION_UP: if(fingerState != FINGER_DRAGGING) { fingerState = FINGER_RELEASED; // Your onClick codes } else if (fingerState == FINGER_DRAGGING) fingerState = FINGER_RELEASED; else fingerState = FINGER_UNDEFINED; break; case MotionEvent.ACTION_MOVE: if (fingerState == FINGER_TOUCHED || fingerState == FINGER_DRAGGING) fingerState = FINGER_DRAGGING; else fingerState = FINGER_UNDEFINED; break; default: fingerState = FINGER_UNDEFINED; } return false; } });
我认为你也可以使用 MotionEvent.ACTION _ UP 状态,例如:
@Override public boolean onTouch(View v, MotionEvent event) { switch (v.getId()) { case R.id.iv: if (event.getAction() == MotionEvent.ACTION_UP) { if (isheadAndFootShow == false) { headLayout.setVisibility(View.VISIBLE); footLayout.setVisibility(View.VISIBLE); isheadAndFootShow = true; } else { headLayout.setVisibility(View.INVISIBLE); footLayout.setVisibility(View.INVISIBLE); isheadAndFootShow = false; } return true; } break; } return false; }
WebViewClient.shouldOverrideUrlLoading可能会有帮助。我们有一个类似的要求,在我们的应用程序。尚未尝试。
WebViewClient.shouldOverrideUrlLoading
这对我有用
webView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // Do what you want return false; } });
这是因为它绑定到网页视图,而不是按钮。我在执行。按钮没有影响,但是网页视图中的页面有影响。
哈米德雷扎的解决方案几乎对我起作用了。
我从实验中注意到,一个简单的点击通常有2-5个动作移动事件。检查行动向下和向上之间的时间更简单,而且行为更像我期望的那样。
private class CheckForClickTouchLister implements View.OnTouchListener { private final static long MAX_TOUCH_DURATION = 100; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: m_DownTime = event.getEventTime(); //init time break; case MotionEvent.ACTION_UP: if(event.getEventTime() - m_DownTime <= MAX_TOUCH_DURATION) //On click action break; default: break; //No-Op } return false; }
点击事件在 webView 中,onTouch 的工作原理如下:
imagewebViewNewsChart.setOnTouchListener(new View.OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction()==MotionEvent.ACTION_MOVE){ return false; } if (event.getAction()==MotionEvent.ACTION_UP){ startActivity(new Intent(this,Example.class)); } return false; } });
我几乎尝试了所有的答案,其中一些几乎对我有效,但没有一个答案是完美的。所以这是我的解决办法。对于这个解决方案,您需要在 HTML 主体标记中添加 onclick属性。因此,如果您不能修改 HTML 文件,那么这个解决方案将不适合您。
onclick
步骤1: 在 HTML body 标记中添加 onclick属性,如下所示:
<body onclick="ok.performClick(this.value);"> <h1>This is heading 1</h1> <p>This is para 1</p> </body>
步骤2: 我们无法在 performClick方法的主线程上执行任何操作,因此需要添加 Handler类:
performClick
private final Handler handler = new Handler(this); // class-level variable private static final int CLICK_ON_WEBVIEW = 1; // class-level variable
实现 Handler.Callback到您的类并重写 handleMessage
Handler.Callback
handleMessage
@Override public boolean handleMessage(Message message) { if (message.what == CLICK_ON_WEBVIEW) { Toast.makeText(getActivity(), "WebView clicked", Toast.LENGTH_SHORT).show(); return true; } return false; }
第三步: 在应用程序中实现 addJavascriptInterface来处理单击监听器:
addJavascriptInterface
webView.addJavascriptInterface(new Object() { @JavascriptInterface public void performClick(String string) { handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 0); } }, "ok");
我假设在向下和向上之间没有动作时有一个点击。
lastTouchAction = -1; myWebView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_UP && lastTouchAction == MotionEvent.ACTION_DOWN){ //do something } lastTouchAction = event.getAction(); return false; } });