Comment puis-je détecter si Android WebView a consommé un événement tactile? onTouchEvent
renvoie toujours true et le WebViewClient
de onUnhandledInputEvent
n’est jamais déclenché.
J’ai plusieurs WebViews dans TwoDScrollView. Comme son nom l’indique, le TwoDScrollView peut défiler verticalement et horizontalement. Le contenu de TwoDScrollView peut être agrandi ou réduit. Lorsque l’utilisateur fait glisser son doigt ou utilise le pincement pour zoomer, je souhaite envoyer l’événement tactile à:
J’ai partiellement réalisé cela en utilisant les méthodes canScrollHorizontally
et canScrollVertically
. Mais ces méthodes ne fonctionnent que pour le “défilement natif”. Toutefois, dans certains cas, du JavaScript à l’intérieur de WebView consum l’événement tactile, par exemple Google Maps. Dans ce cas, les méthodes renvoient false. Y a-t-il un moyen de savoir si le contenu de WebView consum les événements tactiles, c.-à-d. Qu’il est défilable / zoomable? Je ne peux pas changer le contenu de WebView, ma question est donc différente de celle-ci .
J’ai envisagé de vérifier les gestionnaires tactiles en exécutant du JavaScript dans Webview par la méthode AssessJavaScript, mais selon cette réponse, il n’y a pas de moyen facile d’y parvenir et la page peut également contenir d’autres iframes nesteds. Toute aide serait appréciée.
onTouchEvent
de WebView et lu super.onTouchEvent()
qui renvoie toujours true, peu importe quoi. canScrollHorizontally
et canScrollVertically
ne canScrollVertically
que partiellement ce problème, comme mentionné ci-dessus onScrollChanged
n’est pas utile non plus WebViewClient.onUnhandledInputEvent
n’est jamais déclenché evaluateJavaScript
, mais c’est une solution très compliquée et moche Debug.startMethodTracing
. J’ai découvert qu’il se propage comme suit:
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
nativeOnTouchEvent
et je ne sais pas ce qui se passe avec lui. Quoi qu’il en soit, onTouchEvent
renvoie toujours la valeur true et même s’il était possible de savoir quelque part si l’événement était consommé ou non, il faudrait utiliser des méthodes privées qui sont également très laides. Je n’ai pas besoin de savoir comment intercepter les événements tactiles envoyés à WebView, mais si WebView les consum, c’est-à-dire les utiliser pour faire quelque chose, comme faire défiler, faire glisser, etc.
Selon ce rapport , pas possible. Si le code Web est sous votre contrôle, vous pouvez implémenter une interface JavaScript pour contourner ce problème. Sinon, je crains qu’il n’y ait pas de solution ici.
Vous pouvez transmettre tous touch
événements touch
à GestureDetector
en onTouchEvent
de WebView
. Vous pouvez ainsi savoir quand Android WebView consum des événements tactiles n’importe où et à tout moment en écoutant GestureDetector
.
Essayez comme ceci:
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 Ssortingng text) { Toast t = Toast.makeText(context, text, Toast.LENGTH_SHORT); t.show(); } }
J’espère que tu seras inspiré.
Ce code gérera vos événements de défilement dans une vue Web. Ceci intercepte les événements de clic et de clic, et compare les positions de chacun. Peu importe que le contenu de la vue Web soit défilable, comparez simplement les coordonnées dans la zone de la vue 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; } }
Vous pouvez également essayer de contrôler la vitesse du balayage, pour le détecter comme un véritable balayage ou défilement.
J’espère que cela vous aide.
Essayez de définir l’ android:isClickable="true"
dans le XML et créez un onClickListener
dans le code Java.