How can I get onclick event on webview in android?

AndroidAndroid Webview

Android Problem Overview


I want to know when the user clicks on webview but not on a hyperlink. On that click I want to show/hide a view of my activity that holds a webview. Any suggestion?

Android Solutions


Solution 1 - Android

I took a look at this and I found that a WebView doesn't seem to send click events to an OnClickListener. If anyone out there can prove me wrong or tell me why then I'd be interested to hear it.

What I did find is that a WebView will send touch events to an OnTouchListener. It does have its own onTouchEvent method but I only ever seemed to get MotionEvent.ACTION_MOVE using that method.

So given that we can get events on a registered touch event listener, the only problem that remains is how to circumvent whatever action you want to perform for a touch when the user clicks a URL.

This can be achieved with some fancy Handler footwork by sending a delayed message for the touch and then removing those touch messages if the touch was caused by the user clicking a URL.

Here's an example:

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


Solution 2 - Android

You can implement an OnClickListener via OnTouchListener:

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

Solution 3 - Android

Hamidreza's solution almost worked for me.

I noticed from experimentation that a simple tap usually has 2-5 action move events. Checking the time between action down and up was simpler and behaved more like what I expected.

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

Solution 4 - Android

On Click event On webView works in onTouch like this:

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

Solution 5 - Android

I think you can also use MotionEvent.ACTION_UP state, example:

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

Solution 6 - Android

I have tried almost all the answers and some of them almost worked for me but none of these answers work perfectly. So here is my solution. For this solution, you will need to add onclick attribute in the HTML body tag. So if you can not modify the HTML file then this solution won't work for you.

Step 1: add onclick attribute in the HTML body tag like this:

<body onclick="ok.performClick(this.value);">
	<h1>This is heading 1</h1>
	<p>This is para 1</p>
</body>

Step 2: We can not perform any action on main thread from performClick method so need to add Handler class:

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

implement Handler.Callback to your class and the override 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;
}

Step 3: implement addJavascriptInterface in your app to handle click listener:

webView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public void performClick(String string) {
        handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 0);
    }
}, "ok");

Solution 7 - Android

This works for me

webView.setOnTouchListener(new View.OnTouchListener() {
							@Override
							public boolean onTouch(View v, MotionEvent event) {
								// Do what you want
								return false;
							}
						});

Solution 8 - Android

WebViewClient.shouldOverrideUrlLoading might be helpful. We are having a similar requirement in one of our app. Not tried yet.

Solution 9 - Android

Thats because its tied to the web view not the button. I had the same problem after implementing. The button had no affect but the page in the web view did.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArslan AnwarView Question on Stackoverflow
Solution 1 - AndroidLouthView Answer on Stackoverflow
Solution 2 - AndroidHamidreza HosseinkhaniView Answer on Stackoverflow
Solution 3 - AndroidbduhbyaView Answer on Stackoverflow
Solution 4 - AndroidRaza BalochView Answer on Stackoverflow
Solution 5 - AndroidwangzhengyiView Answer on Stackoverflow
Solution 6 - AndroidFaisal ShaikhView Answer on Stackoverflow
Solution 7 - AndroidSpyZipView Answer on Stackoverflow
Solution 8 - AndroidyogiamView Answer on Stackoverflow
Solution 9 - AndroidFranticCityView Answer on Stackoverflow