studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android webview

programacion - Compruebe si Android WebView consume eventos táctiles



manual de programacion android pdf (4)

Este código manejará sus eventos de desplazamiento en una vista web. Esto captura los eventos de clic y clic arriba, y compara las posiciones de cada uno. No importa que el contenido dentro de la vista web sea desplazable, solo compare las coordenadas en el área de la vista web.

public class MainActivity extends Activity implements View.OnTouchListener, Handler.Callback { private float x1,x2,y1,y2; //x1, y1 is the start of the event, x2, y2 is the end. static final int MIN_DISTANCE = 150; //min distance for a scroll event private static final int CLICK_ON_WEBVIEW = 1; private static final int CLICK_ON_URL = 2; private static final int UP_ON_WEBVIEW = 3; private final Handler handler = new Handler(this); public WebView webView; private WebViewClient client; private WebAppInterface webAppInt = new WebAppInterface(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView)findViewById(R.id.myWebView); webView.setOnTouchListener(this); client = new WebViewClient(); webView.setWebViewClient(client); webView.loadDataWithBaseURL("file:///android_asset/", "myweb.html", "text/html", "UTF-8", ""); } //HERE START THE IMPORTANT PART @Override public boolean onTouch(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); } else if (v.getId() == R.id.myWebView && event.getAction() == MotionEvent.ACTION_UP){ x2 = event.getX(); y2 = event.getY(); handler.sendEmptyMessageDelayed(UP_ON_WEBVIEW, 200); } return false; } @Override public boolean handleMessage(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); return true; } if (msg.what == CLICK_ON_WEBVIEW){ //Handle the click in the webview Toast.makeText(this, "WebView clicked", Toast.LENGTH_SHORT).show(); return true; } if (msg.what == UP_ON_WEBVIEW){ float deltaX = x2 - x1; //horizontal move distance float deltaY = y2 - y1; //vertical move distance if ((Math.abs(deltaX) > MIN_DISTANCE) && (Math.abs(deltaX) > Math.abs(deltaY))) { // Left to Right swipe action if (x2 > x1) { //Handle the left to right swipe Toast.makeText(this, "Left to Right swipe", Toast.LENGTH_SHORT).show (); } // Right to left swipe action else { //Handle the right to left swipe Toast.makeText(this, "Right to Left swipe", Toast.LENGTH_SHORT).show (); } } else if ((Math.abs(deltaY) > MIN_DISTANCE) && (Math.abs(deltaY) > Math.abs(deltaX))) { // Top to Bottom swipe action if (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 SCROLLUP else { getActionBar().hide(); Toast.makeText(this, "Bottom to Top swipe [Hide Bar]", Toast.LENGTH_SHORT).show (); } } return true; } return false; } }

También puede intentar controlar la velocidad del deslizamiento, para detectarlo como un deslizamiento o desplazamiento real.

Espero que eso te ayude.

Version corta

¿Cómo puedo detectar si Android WebView consumió un evento táctil? onTouchEvent siempre devuelve verdadero y WebViewClient de onUnhandledInputEvent nunca se activa.

Versión detallada

Tengo múltiples WebViews dentro de TwoDScrollView. Como su nombre lo indica, TwoDScrollView se puede desplazar tanto vertical como horizontalmente. El contenido de TwoDScrollView se puede acercar / alejar. Cuando el usuario arrastra su dedo o usa pellizcar para hacer zoom, quiero enviar el evento táctil para:

  • WebView si su contenido es desplazable / ampliable (es decir, solo el interior de WebView se desplazará / ampliará)
  • TwoDScrollView si la condición anterior es falsa (todo el contenido de TwoDScrollView se desplazará / ampliará)

Lo he logrado parcialmente mediante el uso de los métodos canScrollHorizontally y canScrollVertically . Pero estos métodos solo funcionan para el "desplazamiento nativo". Sin embargo, en algunos casos, algunos JavaScript dentro de WebView consumen el evento táctil, por ejemplo, Google Maps. En este caso, los métodos devuelven falso. ¿Hay alguna forma de averiguar si el contenido de WebView consume los eventos táctiles, es decir, es desplazable / ampliable? No puedo cambiar el contenido de WebView, por lo tanto, mi pregunta es diferente de esta .

He considerado verificar los controladores táctiles ejecutando algo de JavaScript dentro de la vista web mediante el método evalJavaScript, pero de acuerdo con esta respuesta no hay una manera fácil de lograr esto y también la página puede tener otros iframes anidados. Cualquier ayuda será apreciada.

Lo que ya he probado

  1. onTouchEvent de WebView y leí super.onTouchEvent() que siempre devuelve verdadero, sin importar qué.
  2. canScrollHorizontally y canScrollVertically solo resuelven parcialmente este problema, como se mencionó anteriormente
  3. onScrollChanged tampoco es útil
  4. WebViewClient.onUnhandledInputEvent nunca se activa
  5. Pensé en usar JavaScript a través de evaluateJavaScript , pero es una solución muy complicada y fea.
  6. Traté de rastrear el MotionEvent por Debug.startMethodTracing . Descubrí que se propaga de la siguiente manera:
    • android.webkit.WebView.onTouchEvent
    • com.android.webview.chromium.WebViewChromium.onTouchEvent
    • com.android.org.chromium.android_webview.AwContents.onTouchEvent
    • com.android.org.chromium.android_webview.AwContents$AwViewMethodsImpl.onTouchEvent
    • com.android.org.chromium.content.browser.ContentViewCore.onTouchEventImpl
    • Según el código fuente de ContentViewCore, el evento táctil termina en un método nativo nativeOnTouchEvent y no sé qué más sucede con él. De todos modos, onTouchEvent siempre devuelve verdadero e incluso si fuera posible averiguar en algún lugar si el evento se consumió o no, requeriría el uso de métodos privados que también es bastante feo.

Nota

No necesito saber cómo interceptar eventos táctiles enviados a WebView, sino si WebView los está consumiendo, es decir, si los está utilizando para hacer algo, como desplazarse, arrastrar, etc.


Intente configurar android:isClickable="true" en el XML y cree un onClickListener en el código Java.


Puede pasar todos los eventos touch a GestureDetector anulando onTouchEvent de WebView , para que pueda saber cuándo Android WebView está consumiendo eventos táctiles en cualquier lugar, en cualquier momento al escuchar GestureDetector .

Intenta así:

public class MyWebView extends WebView { private Context context; private GestureDetector gestDetector; public MyWebView(Context context) { super(context); this.context = context; gestDetector = new GestureDetector(context, gestListener); } @Override public boolean onTouchEvent(MotionEvent event) { return gd.onTouchEvent(event); } GestureDetector.SimpleOnGestureListener gestListener= new GestureDetector.SimpleOnGestureListener() { public boolean onDown(MotionEvent event) { return true; } public boolean onFling(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 here return true; } }; void show_toast(final String text) { Toast t = Toast.makeText(context, text, Toast.LENGTH_SHORT); t.show(); } }

Espero que te inspires.


Según este informe de problema , no es posible. Si el código web está bajo su control, puede implementar alguna interfaz JavaScript para solucionar esto. Si no, me temo que no hay solución aquí.