【问题标题】:Fling Gesture and Webview in AndroidAndroid 中的 Fling 手势和 Webview
【发布时间】:2016-07-29 23:06:36
【问题描述】:

我有一个 webview 控件,它需要支持 Android 中的投掷手势,以便调出新记录(加载新数据)。这发生在扩展 Activity 的类中。我见过的所有示例都展示了如何为 textview 实现手势支持,但对 webview 没有任何支持。

我需要对左右甩动执行不同的操作。任何代码帮助都将不胜感激,因为这完全让我难过。

这是我的基本 onCreate 和我的课程

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

....


}

}

【问题讨论】:

    标签: android sdk webview gesture


    【解决方案1】:

    创建一个 GestureListener 和一个 GestureDetector。通过覆盖 webview 的 onTouchEvent 调用 GestureDetector.onTouchEvent。

    顺便说一句,您也可以只覆盖 Activity onTouchEvent。如果您需要,我可以发布一些代码。

    编辑:按要求编写代码。

    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。我认为默认情况下 WebView 触摸事件是指当它显示缩放控件等时?我没有测试那个。我发现实现自己的手势检测效果最好(但不确定它是否在 WebView 上效果最好)。您需要将触摸事件视为三个不同的组件。按下、移动(如果有)和按下释放,随着按下、移动、释放总是发生。

    如果您在 onDown 上执行 return false,则该操作应传递给 WebView 触摸事件处理程序,但 iirc 它会停止将后续事件传递给 GestureDetector。这是我实现自己的基于 Android 源代码的一半原因。 iirc 我从索尼爱立信教程中得到了这个想法,该教程可以从市场上下载。它是显示代码的 3D 列表,而且很容易适应。

    【讨论】:

    • 我试过这个方法,它似乎屏蔽了默认的 WebView 触摸事件。我也尝试在 Activity 而不是 WebView 上实现它,但它也不起作用。似乎 onDown 上的覆盖是问题所在,但由于没有它似乎无法工作,所以我不确定如何在不破坏 WebView 正常操作的情况下让它工作。有什么其他可以尝试的建议吗?
    • @littleFluffyKitty。请查看我对我的回答的编辑。如果我能提供更多帮助,请告诉我。
    • 我仍然同意@littleFluffyKitty - 即使在编辑之后,它看起来这段代码添加了投掷功能,但禁用了所有默认的 WebView 触摸事件,这违背了目的。我感兴趣的是滚动和点击,我不应该自己重写。
    • @Han:如果你不学习如何编码而不仅仅是使用stackoverflow进行c&p,你会意识到你可以查看android源代码和sdk示例并弄清楚。
    • 哇太棒了,它真的有效......!
    【解决方案2】:

    我更新了代码,现在允许在用户没有放弃的情况下调用本机事件处理程序

    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;
            }
        };
    }
    

    【讨论】:

    • 我不清楚第一个if 子句在onFling 方法中的用途。它基本上忽略了在X 轴上从 80 到 1200 开始的任何手势事件。这不会忽略这些操作中的绝大多数吗?
    【解决方案3】:

    @Han,请原谅@techiServices 他不经意的回答。

    上面代码的问题是,在所有情况下,它都会为 onFling 和 onDown 返回 true。相反,您想要的是为您未处理的事件或您未处理的事件中的条件返回 false。或者实际上,在 onTouchEvent 中,您可以通过返回将调用传递给基类

    super.onTouchEvent(event);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多