Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android singleTap/OnClick in WebView

i am loading Web view with Html String,i want to show navigate buttons when the user tap on the web view,i tried With onTouch listener,touch event raises when scrolling and tapping but i want to catch single tap/clickEvent, Not scroll Event touches..., i implemented SetOnClickListener for both WebView and LinearLayout,None of them is not working for me Any help regarding this

like image 324
Bad Boy Avatar asked May 06 '11 05:05

Bad Boy


3 Answers

I modified Zsolt Safrany's answer and I put his onInterceptTouchEvent's content into webview's onTouch method and it worked.

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;
}           });
like image 106
ACengiz Avatar answered Nov 13 '22 18:11

ACengiz


WebView does not support the OnClickListener. And also it does consume touch events even though nothing happened on the web page thus ancestors views (like your LinearLayout) don't have any chance to produce an OnClick event. It is very unfortunate.

As a workaround I extended a RelativeLayout and put my WebView inside of it. In the RelativeLayout I've overwritten onInterceptTouchEvent and were looking for tap events. If a tap is detected then the RelativeLayout's OnClickListener is invoked with performClick().

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

}

like image 39
Zsolt Safrany Avatar answered Nov 13 '22 20:11

Zsolt Safrany


From this page: http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/

It seems that touch events must be properly trapped. Check this out:

@Override
public boolean dispatchTouchEvent(MotionEvent e){
    super.dispatchTouchEvent(e);
    return mGestureDetector.onTouchEvent(e);
} 
like image 21
John Stewart Avatar answered Nov 13 '22 19:11

John Stewart