Как переопределить некоторые события жестов через веб-просмотр, но пропустить другие? - PullRequest
4 голосов
/ 02 марта 2011

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

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

Я нашел это: 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();
 }
}
}

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

Ответы [ 2 ]

7 голосов
/ 02 марта 2011

Что вы хотите сделать здесь, это добавить код в ваш 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.

1 голос
/ 06 июня 2012

Я написал класс, который расширен от 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)); 
}  
}
...