2010-11-19 33 views
11

我有一个webview控件,需要在Android中支持该手势,以便创建新记录(加载新数据)。这发生在扩展Activity的类中。我见过的所有示例都演示了如何实现textview的手势支持,但没有为webview提供任何支持。在Android中弹出手势和Web视图

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

这里是我的基本的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() { 

.... 


} 

} 

回答

11

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

你也可以重写Activity onTouchEvent btw。如果您需要,我可以发布一些代码。

编辑:代码按要求。

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执行了返回false,则该操作应传递给WebView触控事件处理程序,但iirc会停止将后续事件传递给GestureDetector。这是我实现基于Android源代码的自己的原因的一半。 iirc我从索尼爱立信教程中获得了可从市场上下载的想法。这是3D列表,显示了代码并很容易适应。

+0

我已经尝试过这种方法,它似乎阻止了默认的WebView触摸事件。我也尝试过在Activity上实现而不是在WebView上,它也没有工作。这似乎是onDown的重写是问题,但由于它似乎没有工作,我不知道如何得到这个工作,而不会搞乱WebView的正常操作。任何其他建议尝试? – cottonBallPaws 2011-01-05 21:56:50

+1

@littleFluffyKitty。请在我的回答中看到我的编辑。让我知道如果我能有更多的帮助。 – techiServices 2011-01-05 23:18:26

+0

我同意@littleFluffyKitty仍然 - 即使在编辑后,它看起来这个代码增加了一触即发的功能,但禁用所有的默认WebView触摸事件,哪种打败了目的。我感兴趣的是滚动和点击,我不应该重写自己。 – Han 2011-05-16 02:55:36

2

@Han,原谅@techi为他不需要的答案服务。

上述代码的问题是,在所有情况下,它都会在onFling和onDown中返回true。你想要的是对于你不处理的事件或者你不处理的事件中的条件返回false。或者实际上,在你的onTouchEvent可以通过返回

super.onTouchEvent(event); 
4

我更新的代码通过调用基类,它将会允许调用本地事件处理程序,如果用户没有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; 
     } 
    }; 
}