如何在 android 中获得 webview 上的 onclick 事件?

我想知道什么时候用户点击网络视图,但不是在一个超链接。在单击时,我想显示/隐藏一个包含 webview 的活动视图。有什么建议吗?

133677 次浏览

我看了看这个,我发现一个 WebView似乎不发送点击事件到一个 OnClickListener。如果有人能证明我错了或者告诉我为什么,我会很感兴趣的。

我所发现的是,一个 WebView将发送触摸事件到一个 OnTouchListener。它确实有自己的 onTouchEvent方法,但是我似乎只能用这个方法得到 MotionEvent.ACTION_MOVE

因此,既然我们可以在已注册的触摸事件监听器上获取事件,那么剩下的唯一问题就是当用户单击 URL 时,如何规避您想要执行的任何触摸操作。

这可以通过一些花哨的 Handler步骤来实现,即发送触摸延迟消息,然后如果触摸是由用户单击 URL 引起的,则删除这些触摸消息。

这里有一个例子:

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可能会有帮助。我们有一个类似的要求,在我们的应用程序。尚未尝试。

这对我有用

webView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// Do what you want
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 文件,那么这个解决方案将不适合您。

步骤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类:

private final Handler handler = new Handler(this); // class-level variable
private static final int CLICK_ON_WEBVIEW = 1; // class-level variable

实现 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来处理单击监听器:

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;
}
});