【发布时间】:2011-05-06 05:34:54
【问题描述】:
我正在使用 Html 字符串加载 Web 视图,我想在用户点击 Web 视图时显示导航按钮,我尝试使用 onTouch 侦听器,滚动和点击时会引发触摸事件,但是 我想捕捉单击/clickEvent,不滚动事件触摸...,我为 WebView 和 LinearLayout 实现了 SetOnClickListener,它们都不适合我 有关此的任何帮助
【问题讨论】:
我正在使用 Html 字符串加载 Web 视图,我想在用户点击 Web 视图时显示导航按钮,我尝试使用 onTouch 侦听器,滚动和点击时会引发触摸事件,但是 我想捕捉单击/clickEvent,不滚动事件触摸...,我为 WebView 和 LinearLayout 实现了 SetOnClickListener,它们都不适合我 有关此的任何帮助
【问题讨论】:
WebView 不支持OnClickListener。即使网页上没有发生任何事情,它也会消耗触摸事件,因此祖先视图(如您的LinearLayout)没有任何机会产生 OnClick 事件。太可惜了。
作为一种解决方法,我扩展了 RelativeLayout 并将我的 WebView 放入其中。在RelativeLayout 中,我已经覆盖了onInterceptTouchEvent 并正在寻找点击事件。如果检测到点击,则使用performClick() 调用RelativeLayout 的OnClickListener。
public class TapAwareRelativeLayout extends RelativeLayout {
private final float MOVE_THRESHOLD_DP = 20 * getResources().getDisplayMetrics().density;
private boolean mMoveOccured;
private float mDownPosX;
private float mDownPosY;
public TapAwareRelativeLayout(Context context) {
super(context);
}
public TapAwareRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mMoveOccured = false;
mDownPosX = ev.getX();
mDownPosY = ev.getY();
break;
case MotionEvent.ACTION_UP:
if (!mMoveOccured) {
// TAP occured
performClick();
}
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(ev.getX() - mDownPosX) > MOVE_THRESHOLD_DP || Math.abs(ev.getY() - mDownPosY) > MOVE_THRESHOLD_DP) {
mMoveOccured = true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
}
【讨论】:
我修改了 Zsolt Safrany 的答案,并将他的 onInterceptTouchEvent 的内容放入 webview 的 onTouch 方法中,它起作用了。
webview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.v(TAG,"Got a touch event in the web view!");
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mMoveOccured = false;
mDownPosX = ev.getX();
mDownPosY = ev.getY();
break;
case MotionEvent.ACTION_UP:
if (!mMoveOccured) {
//click operation is here
}
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(ev.getX() - mDownPosX) > MOVE_THRESHOLD_DP || Math.abs(ev.getY() - mDownPosY) > MOVE_THRESHOLD_DP) {
mMoveOccured = true;
}
break;
}
return false;
} });
【讨论】:
从此页面:http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/
似乎必须正确捕获触摸事件。看看这个:
@Override
public boolean dispatchTouchEvent(MotionEvent e){
super.dispatchTouchEvent(e);
return mGestureDetector.onTouchEvent(e);
}
【讨论】:
工作代码::
final Boolean[] mMoveOccured = new Boolean[1];
final float[] mDownPosX = new float[1];
final float[] mDownPosY = new float[1];
final float MOVE_THRESHOLD_DP = 20 * getResources().getDisplayMetrics().density;
userPic.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mMoveOccured[0] = false;
mDownPosX[0] = event.getX();
mDownPosY[0] = event.getY();
break;
case MotionEvent.ACTION_UP:
if (!mMoveOccured[0]) {
Toast.makeText(v.getContext(), "Webview pressed", Toast.LENGTH_SHORT).show();
}
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(event.getX() - mDownPosX[0]) > MOVE_THRESHOLD_DP || Math.abs(event.getY() - mDownPosY[0]) > MOVE_THRESHOLD_DP) {
mMoveOccured[0] = true;
}
break;
}
return false;
}
});
【讨论】: