Check If Android Webview Is Consuming Touch Events
Solution 1:
According to this issue report, not possible. If the web code is under your control, you can implement some JavaScriptInterface to workaround this. If not, I am afraid there is no solution here.
Solution 2:
You can pass all touch
events to GestureDetector
by overriding onTouchEvent
of WebView
, so you can know when Android WebView is consuming touch events anywhere, anytime by listening to GestureDetector
.
Try like this:
publicclassMyWebViewextendsWebView {
private Context context;
private GestureDetector gestDetector;
publicMyWebView(Context context) {
super(context);
this.context = context;
gestDetector = newGestureDetector(context, gestListener);
}
@OverridepublicbooleanonTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);
}
GestureDetector.SimpleOnGestureListener gestListener= newGestureDetector.SimpleOnGestureListener() {
publicbooleanonDown(MotionEvent event) {
returntrue;
}
publicbooleanonFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
//if (event1.getRawX() > event2.getRawX()) {// show_toast("swipe left");//} else {// show_toast("swipe right");//}//you can trace any touch events herereturntrue;
}
};
voidshow_toast(final String text) {
Toastt= Toast.makeText(context, text, Toast.LENGTH_SHORT);
t.show();
}
}
I hope you be inspired.
Solution 3:
This code will handle your scrolling events in a webview. This catch the click down and the click up events, and compares the positions of each one. It never minds that the content within the webview is scrollable, just compare the coordinates in the area of webview.
publicclassMainActivityextendsActivityimplementsView.OnTouchListener, Handler.Callback {
privatefloat x1,x2,y1,y2; //x1, y1 is the start of the event, x2, y2 is the end.staticfinalintMIN_DISTANCE=150; //min distance for a scroll eventprivatestaticfinalintCLICK_ON_WEBVIEW=1;
privatestaticfinalintCLICK_ON_URL=2;
privatestaticfinalintUP_ON_WEBVIEW=3;
privatefinalHandlerhandler=newHandler(this);
public WebView webView;
private WebViewClient client;
privateWebAppInterfacewebAppInt=newWebAppInterface(this);
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView)findViewById(R.id.myWebView);
webView.setOnTouchListener(this);
client = newWebViewClient();
webView.setWebViewClient(client);
webView.loadDataWithBaseURL("file:///android_asset/", "myweb.html", "text/html", "UTF-8", "");
}
//HERE START THE IMPORTANT PART@OverridepublicbooleanonTouch(View v, MotionEvent event) {
if (v.getId() == R.id.myWebView && event.getAction() == MotionEvent.ACTION_DOWN){
x1 = event.getX();
y1 = event.getY();
handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 200);
} elseif (v.getId() == R.id.myWebView && event.getAction() == MotionEvent.ACTION_UP){
x2 = event.getX();
y2 = event.getY();
handler.sendEmptyMessageDelayed(UP_ON_WEBVIEW, 200);
}
returnfalse;
}
@OverridepublicbooleanhandleMessage(Message msg) {
if (msg.what == CLICK_ON_URL){ //if you clic a link in the webview, thats not a scroll
handler.removeMessages(CLICK_ON_WEBVIEW);
handler.removeMessages(UP_ON_WEBVIEW);
returntrue;
}
if (msg.what == CLICK_ON_WEBVIEW){
//Handle the click in the webview
Toast.makeText(this, "WebView clicked", Toast.LENGTH_SHORT).show();
returntrue;
}
if (msg.what == UP_ON_WEBVIEW){
floatdeltaX= x2 - x1; //horizontal move distancefloatdeltaY= y2 - y1; //vertical move distanceif ((Math.abs(deltaX) > MIN_DISTANCE) && (Math.abs(deltaX) > Math.abs(deltaY)))
{
// Left to Right swipe actionif (x2 > x1)
{
//Handle the left to right swipe
Toast.makeText(this, "Left to Right swipe", Toast.LENGTH_SHORT).show ();
}
// Right to left swipe actionelse
{
//Handle the right to left swipe
Toast.makeText(this, "Right to Left swipe", Toast.LENGTH_SHORT).show ();
}
}
elseif ((Math.abs(deltaY) > MIN_DISTANCE) && (Math.abs(deltaY) > Math.abs(deltaX)))
{
// Top to Bottom swipe actionif (y2 > y1)
{
//Handle the top to bottom swipe
Toast.makeText(this, "Top to Bottom swipe", Toast.LENGTH_SHORT).show ();
}
// Bottom to top swipe action -- I HIDE MY ACTIONBAR ON SCROLLUPelse
{
getActionBar().hide();
Toast.makeText(this, "Bottom to Top swipe [Hide Bar]", Toast.LENGTH_SHORT).show ();
}
}
returntrue;
}
returnfalse;
}
}
You can also try to control the speed of the swipe, to detect it as a real swipe or scrolling.
I hope that helps you.
Solution 4:
Try to set the android:isClickable="true"
in the XML and create an onClickListener
in the Java code.
Solution 5:
Actually now Touch Actions are not supported for webview. But some workarounds are available; I am going to show it with a longpress example : I am using Pointoption because i will get the coordinate of element and will use it for longpress.
publicvoidlongpress(PointOption po) {
//first you need to switch to native view
driver.switchToNativeView();
TouchActionaction=newTouchAction((PerformsTouchActions) driver);
action.longPress(po).waitAction(WaitOptions.waitOptions(Duration.ofSeconds(2)));
action.release();
action.perform();
driver.switchToDefaultWebView();
}
For to get the coordinate of element i designed below methood
public PointOption getElementLocation(WebElement element) {
int elementLocationX;
int elementLocationY;
//get element location in webview
elementLocationX = element.getLocation().getX();
elementLocationY = element.getLocation().getY();
//get the center location of the elementintelementWidthCenter= element.getSize().getWidth() / 2;
intelementHeightCenter= element.getSize().getHeight() / 2;
intelementWidthCenterLocation= elementWidthCenter + elementLocationX;
intelementHeightCenterLocation= elementHeightCenter + elementLocationY;
//calculate the ratio between actual screen dimensions and webview dimensionsfloatratioWidth= device.getDeviceScreenWidth() / ((MobileDevice) device)
.getWebViewWidth().intValue();
floatratioHeight= device.getDeviceScreenHeight() / ((MobileDevice) device)
.getWebViewHeight().intValue();
//calculate the actual element location on the screen , if needed you can increase this value,for example i used 115 for one of my mobile devices.intoffset=0;
floatelementCenterActualX= elementWidthCenterLocation * ratioWidth;
floatelementCenterActualY= (elementHeightCenterLocation * ratioHeight) + offset;
float[] elementLocation = {elementCenterActualX, elementCenterActualY};
int elementCoordinateX, elementCoordinateY;
elementCoordinateX = (int) Math.round(elementCenterActualX);
elementCoordinateY = (int) Math.round(elementCenterActualY);
PointOptionpo= PointOption.point(elementCoordinateX, elementCoordinateY);
return po;
}
now you have a longpress(PointOption po) and getElementLocation(Webelement element) methods that gives you po. Now everything is ready and you can use them as below..
longpress(getElementLocation(driver.findElement(By.id("the selector can be any of them(xpath,css,classname,id etc.)")));
Post a Comment for "Check If Android Webview Is Consuming Touch Events"