2010-11-19 16 views
11

Tengo un control de vista web que necesita para soportar el gesto fling en Android con el fin de abrir un nuevo registro (cargar nuevos datos). Esto ocurre en una clase que extiende la Actividad. Todos los ejemplos que he visto muestran cómo implementar el soporte de gestos para una vista de texto, pero nada para la vista web.Fling Gesture and Webview en Android

Necesito ejecutar diferentes acciones tanto para los alados izquierdos como a la derecha. Cualquier código de ayuda sería apreciado ya que esto me tiene totalmente perplejo.

Aquí es mi onCreate básico y mi clase

import android.app.Activity; 
import android.content.Intent; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.os.Bundle; 
import android.text.Html; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.Window; 

import android.webkit.WebView; 

public class ArticleActivity extends Activity { 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 



    Window w = getWindow(); 

    w.requestFeature(Window.FEATURE_LEFT_ICON); 

    WebView webview = new WebView(this); 
    setContentView(webview); 



    w.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, 
    R.drawable.gq); 




    setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); 
    populateFields(); 
    webview.loadData(question + answer, "text/html", "utf-8"); 



    // 
} 
private void populateFields() { 

.... 


} 

} 

Respuesta

11

Crear un GestureListener y una GestureDetector. Llame al GestureDetector.onTouchEvent al anular la vista web enTouchEvent.

También puede anular la Actividad onTouchEvent btw. Puedo publicar un código si es necesario.

Editar: Código como solicitado.

public class Main extends Activity { 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     MyWebView webview = new MyWebView(this); 
     setContentView(webview); 
    } 

    class MyWebView extends WebView { 
     Context context; 
     GestureDetector gd; 

     public MyWebView(Context context) { 
      super(context); 

      this.context = context; 
      gd = new GestureDetector(context, sogl); 
     } 

     @Override 
     public boolean onTouchEvent(MotionEvent event) { 
      return gd.onTouchEvent(event); 
     } 

     GestureDetector.SimpleOnGestureListener sogl = 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"); 
       } 
       return true; 
      } 
     }; 

     void show_toast(final String text) { 
      Toast t = Toast.makeText(context, text, Toast.LENGTH_SHORT); 
      t.show(); 
     } 
    } 
} 

@littleFluffyKitty. Supongo que por defecto los eventos táctiles de WebView se refieren a cuando se muestran los controles de zoom, etc. No probé eso. Descubrí que la implementación de la detección de gestos propios funciona mejor (aunque no estoy seguro si funcionaría mejor en una WebView). Necesita ver un evento táctil como tres componentes distintos. La presión hacia abajo, el movimiento (si corresponde) y el comunicado de prensa, a medida que se presiona hacia abajo, se mueve, se libera siempre.

Si realiza un return false en onDown, la acción se debe pasar al manejador de evento táctil WebView, pero iirc detiene los sucesos posteriores que se pasan al GestureDetector. Que es la mitad de la razón por la que implemento la mía, que se basa en la fuente de Android. iirc Obtuve la idea de los Tutoriales de Sony Ericsson, que se pueden descargar del mercado. Es la lista 3D que muestra el código y es bastante fácil de adaptar.

+0

I han probado este método y parece bloquear los eventos táctiles WebView por defecto. También intenté implementar esto en la actividad en lugar de WebView y tampoco funcionó. Parecía que la anulación del OnDown es el problema, pero dado que no parece funcionar sin eso, no estoy seguro de cómo hacerlo funcionar sin estropear las operaciones normales del WebView. ¿Alguna sugerencia de algo más que probar? – cottonBallPaws

+1

@littleFluffyKitty. por favor mira mi edición en mi respuesta. avísame si puedo ser de más ayuda. – techiServices

+0

Aún estoy de acuerdo @littleFluffyKitty: incluso después de la edición parece que este código agrega fling capacidades pero deshabilita todos los eventos táctiles WebView por defecto, lo que en cierto modo frustra el propósito. Los que me interesan son desplazamiento y clic, que no debería tener que reescribir yo mismo. – Han

2

@Han, perdona a @techiServices su inesperada respuesta.

El problema con el código anterior es que en todos los casos devuelve verdadero para onFling y onDown. Lo que desea en su lugar es devolver falso para los eventos que no maneja, o para condiciones en esos eventos que no maneja. O, de hecho, en onTouchEvent se podía pasar la llamada a la clase base devolviendo

super.onTouchEvent(event); 
4

He actualizado el código, esto permitirá ahora a llamar a eventos nativos manipuladores si el usuario no flinged

import android.content.Context; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.GestureDetector; 
import android.view.MotionEvent; 
import android.webkit.WebView; 

public class MyWebView extends WebView { 
    private boolean flinged; 

    private static final int SWIPE_MIN_DISTANCE = 320; 
    private static final int SWIPE_MAX_OFF_PATH = 250; 
    private static final int SWIPE_THRESHOLD_VELOCITY = 200; 

    public MyWebView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     gd = new GestureDetector(context, sogl); 
    } 

    GestureDetector gd; 


    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     gd.onTouchEvent(event); 
     if (flinged) { 
      flinged = false; 
      return true; 
     } else { 
      return super.onTouchEvent(event); 
     } 
    } 

    GestureDetector.SimpleOnGestureListener sogl = new GestureDetector.SimpleOnGestureListener() { 
    // your fling code here 
     public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { 
      if (event1.getX() < 1200 && event1.getX() > 80) { 
       return false; 
      } 
      if (Math.abs(event1.getY() - event1.getY()) > SWIPE_MAX_OFF_PATH) 
       return false; 
      if(event1.getX() - event2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
       loadUrl("javascript:changePage('LEFT')"); 
       Log.i("Swiped","swipe left"); 
       flinged = true; 
      } else if (event2.getX() - event1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
       loadUrl("javascript:changePage('RIGHT')"); 
       Log.i("Swiped","swipe right"); 
       flinged = true; 
      } 
      return true; 
     } 
    }; 
}