Как переопределить некоторые события жестов в веб-просмотре, но пропустить другие?

Я все еще разбираюсь во всех тонкостях SDK, так что потерпите меня здесь.

Итак, я пытаюсь реализовать Webview, который сохраняет элементы управления мультитач-масштабированием и вертикальную прокрутку нетронутыми (их обрабатывает класс webview), блокируя горизонтальную прокрутку в Webview и реализуя горизонтальные броски для поиска новых данных.

Я нашел это: Fling Gesture и Webview в Android. Поэтому я взял этот код, чтобы понять, как реализовать это в моем приложении позже, поэтому я работаю оттуда (ответ, конечно).

И начал модифицировать код под себя. Например:

   if (event1.getRawX() > event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100) {
    show_toast("swipe left");
   } else if(event1.getRawX() < event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100){
    show_toast("swipe right");

На самом деле обнаруживает ТОЛЬКО горизонтальные броски.

Однако я не понял, как убедиться, что горизонтальные броски вызывают действие по моему выбору, в то время как вертикальные броски по-прежнему управляют прокруткой рассматриваемого WebView.

Моей первой мыслью было попробовать что-то вроде pageUp/pageDown или scrollTo в веб-просмотре, но это не сработает, поскольку я расширяю класс веб-просмотра до MyWebView и, следовательно, еще не имею экземпляра объекта этого типа.

Это полный код, если нужно:

package test.fling;


import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.webkit.WebView;
import android.widget.Toast;

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

    MyWebView webview = new MyWebView(this);
    webview.loadUrl("http://en.wikipedia.org/wiki/Android");
    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() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100) {
    show_toast("swipe left");
   } else if(event1.getRawX() < event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100){
    show_toast("swipe right");
   } else {
     //MyWebView.pageUp(true); /*can't work, as explained above*/
   }
return true;
  }
 };

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

Любая помощь будет принята с благодарностью. Спасибо!


person Robin Eisenberg    schedule 02.03.2011    source источник


Ответы (2)


Что вы хотите сделать здесь, так это добавить код в ваш onTouchEvent, чтобы проверить возвращаемое значение из onTouchEvent GestureDetector, и если оно ложно, то вызвать суперкласс WebView с событием, например так:

<code>
    @Override 

    public boolean onTouchEvent(MotionEvent event) {

        return (gd.onTouchEvent(event) 
            || super.onTouchEvent(event)); 
    }  
</code>

Затем ваш метод onFling может возвращать true, если вы обрабатываете событие, или false, если вы хотите, чтобы WebView обрабатывал событие. Вам также необходимо изменить onDown, чтобы он возвращал false, чтобы WebView имел шанс получить начальное событие down.

person Roger Powell    schedule 02.03.2011
comment
Спасибо, это сработало отлично. Я понял, что это было return false, чтобы позволить суперклассу справиться с этим, но мне не хватало || супер.onTouchEven. Большое тебе спасибо! - person Robin Eisenberg; 03.03.2011
comment
Я попробовал ваше решение, но я все еще не могу щелкнуть элементы html. Я добавил return false, где у Робина Айзенберга есть //MyWebView.pageUp(true); /*can't work, as explained above*/ и ваш метод onTouchEvent - person Alexander Scholz; 26.08.2013

Я написал класс, который является расширением WebView и может легко обнаруживать удары.

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.webkit.WebView;
import android.widget.Toast;

public class HtmlImageView extends WebView {

Context mContext;
GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector());

public HtmlImageView(Context context) {
    super(context);
    mContext=context;
}

public HtmlImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mContext=context;
}

public HtmlImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    mContext=context;
}

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

class MyGestureDetector extends SimpleOnGestureListener {

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
            float distanceX, float distanceY) {
        return super.onScroll(e1, e2, distanceX, distanceY);
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;
            // right to left swipe
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(mContext, "Left Swipe", Toast.LENGTH_SHORT)
                        .show();
            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(mContext, "Right Swipe", Toast.LENGTH_SHORT)
                        .show();
            }
        } catch (Exception e) {
            // nothing
        }
        return false;
    }
}

public boolean onTouchEvent(MotionEvent event) {

    return (gestureDetector.onTouchEvent(event) 
        || super.onTouchEvent(event)); 
}  
}
person Suat KARAKUSOGLU    schedule 06.06.2012