2010-11-19 7 views
11

J'ai un contrôle webview qui doit supporter le geste de fling dans Android afin de faire apparaître un nouvel enregistrement (charger de nouvelles données). Cela se produit dans une classe qui étend l'activité. Tous les exemples que j'ai vus montrent comment implémenter le support gestuel pour un textview, mais rien pour le webview.Fling Gesture et Webview dans Android

J'ai besoin d'exécuter différentes actions pour les flings gauche et droit. N'importe quelle aide de code serait appréciée car cela m'a totalement bloqué.

Voici mon onCreate de base et ma classe

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() { 

.... 


} 

} 

Répondre

11

Créer un GestureListener et un GestureDetector. Appelez le GestureDetector.onTouchEvent en remplaçant l'onTouchEvent du WebView.

Vous pouvez également remplacer l'activité onTouchEvent btw. Je peux poster du code si vous en avez besoin.

Éditer: Code tel que demandé.

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. Je présume que les événements tactiles WebView par défaut que vous voulez dire quand il fait apparaître les commandes de zoom etc? Je n'ai pas testé ça. J'ai trouvé que la mise en œuvre de sa propre détection de gestes fonctionne le mieux (je ne sais pas si cela fonctionnerait mieux sur un WebView si). Vous devez considérer un événement tactile comme trois composants distincts. La pression vers le bas, le mouvement (le cas échéant), et le communiqué de presse, comme la pression vers le bas, le mouvement, la libération se produisent toujours.

Si vous renvoyez false sur l'onDown, l'action doit être transmise au gestionnaire d'événements WebView touch mais iirc interrompt les événements suivants transmis au GestureDetector. Ce qui est la moitié de la raison pour laquelle je mets en œuvre mon propre qui est basé sur la source Android. iirc J'ai eu l'idée des Tutoriels Sony Ericsson téléchargeables sur le marché. C'est la liste 3D qui montre le code et c'est assez facile à adapter.

+0

I J'ai essayé cette méthode et il semble bloquer les événements tactiles WebView par défaut. J'ai également essayé d'implémenter ceci sur l'activité au lieu du WebView et cela n'a pas fonctionné non plus. Il semble que le problème de l'onDown soit le problème, mais comme cela ne semble pas fonctionner sans cela, je ne suis pas sûr de savoir comment le faire fonctionner sans perturber les opérations normales de WebView. Des suggestions d'autre chose à essayer? – cottonBallPaws

+1

@littleFluffyKitty. s'il vous plaît voir mon edit sur ma réponse. laissez-moi savoir si je peux être plus utile. – techiServices

+0

Je suis d'accord @littleFluffyKitty encore - même après l'édition, il regarde ce code ajoute des capacités de fling mais désactive tous les événements tactiles WebView par défaut, ce qui en quelque sorte va à l'encontre du but. Ceux qui m'intéressent sont scroll et click, que je ne devrais pas avoir à me réécrire. – Han

2

@Han, pardonne @techiServices sa réponse non réclamée.

Le problème avec le code ci-dessus est que dans tous les cas, il renvoie true pour onFling et onDown. Ce que vous voulez à la place est de renvoyer faux pour les événements que vous ne gérez pas, ou pour les conditions dans les événements que vous ne gérez pas. Ou bien, en onTouchEvent vous pouvez passer l'appel à la classe de base en retournant

super.onTouchEvent(event); 
4

Je mis à jour le code, cela permettra maintenant d'appeler des événements natifs gestionnaires si l'utilisateur n'a pas 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; 
     } 
    }; 
}