【发布时间】:2011-07-04 06:24:04
【问题描述】:
我想知道用户何时单击 webview 而不是超链接。在该单击上,我想显示/隐藏包含 web 视图的我的活动视图。有什么建议吗?
【问题讨论】:
-
嗨,Arslan,您有可以发布或链接到的示例吗?
我想知道用户何时单击 webview 而不是超链接。在该单击上,我想显示/隐藏包含 web 视图的我的活动视图。有什么建议吗?
【问题讨论】:
我查看了这个,发现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;
}
});
【讨论】:
Hamidreza's solution 几乎为我工作。
我从实验中注意到,一个简单的点击通常有 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;
}
【讨论】:
On Click 事件 On 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;
}
});
【讨论】:
我想你也可以使用 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;
}
【讨论】:
这对我有用
webView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// Do what you want
return false;
}
});
【讨论】:
我已经尝试了几乎所有的答案,其中一些几乎对我有用,但这些答案都不是完美的。所以这是我的解决方案。对于此解决方案,您需要在 HTML 正文标记中添加 onclick 属性。因此,如果您无法修改 HTML 文件,那么此解决方案将不适合您。
第 1 步: 在 HTML 正文标记中添加 onclick 属性,如下所示:
<body onclick="ok.performClick(this.value);">
<h1>This is heading 1</h1>
<p>This is para 1</p>
</body>
第 2 步: 在您的应用中实现 addJavascriptInterface 来处理点击监听器:
webView.addJavascriptInterface(new Object() {
@JavascriptInterface
public void performClick(String string) {
handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 0);
}
}, "ok");
第 3 步: 我们无法通过 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;
}
【讨论】:
WebViewClient.shouldOverrideUrlLoading 可能会有所帮助。我们的一个应用程序中有类似的要求。还没试过。
【讨论】:
那是因为它与 Web 视图而非按钮相关联。实施后我遇到了同样的问题。按钮没有影响,但 web 视图中的页面有影响。
【讨论】: