{"id":2266,"date":"2013-05-22T22:37:21","date_gmt":"2013-05-22T14:05:53","guid":{"rendered":"https:\/\/programresource.net\/?p=2266"},"modified":"2013-05-22T23:05:53","modified_gmt":"2013-05-22T14:05:53","slug":"go-back-and-forth-in-webview-history-with-finger-gesture","status":"publish","type":"post","link":"https:\/\/programresource.net\/en\/2013\/05\/22\/2266.html","title":{"rendered":"Go back and forth in WebView history with finger gesture"},"content":{"rendered":"<p>It is easy to add Web functionality to Android app using WebView. It is hard to customize contents shown inside webview, but you can customize UIs.<\/p>\n<p>This time, I&#8217;m going to show how to use gesture, swiping finger left \/ right to go back \/ forward in webview history.<\/p>\n<p>GestureDetector class is used for gesture processing. By using this class, not only left \/ right swipe but also double tap or long hold can be assigned to some functions. Be careful not to override too much of \u00a0browser functions.<\/p>\n<p>Use WebView class as base, and create custom WebView class to handle gesture. In sample code below, swiping finger left to right goes back in history, but if there are no more backward history, it will finish app.<\/p>\n<p>First, main activity.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">private BackNotify mNotify = new BackNotify();\r\nprivate Handler mNotifyHandler = null;\r\n\r\n@Override\r\npublic void onCreate(Bundle savedInstanceState) {\r\n\tsuper.onCreate(savedInstanceState);\r\n\r\n\tnfWebView webview;\r\n\twebview = new nfWebView(this);\r\n\r\n\t\/\/register handler for webview terminate notification\r\n\tif(mNotifyHandler == null)\r\n\t\tmNotifyHandler = new Handler();\r\n\twebview.SetNotifyBackHandler(mNotifyHandler, mNotify);\r\n\r\n\t\/\/add view\r\n\tRelativeLayout wholder = (RelativeLayout) findViewById(R.id.web);\r\n\twholder.addView(webview, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,RelativeLayout.LayoutParams.FILL_PARENT));\r\n}\r\n\r\n\/\/called when Back gesture is done while no more backward history\r\npublic class BackNotify implements Runnable { \/\/notify from nfWebView\r\n\t@Override\r\n\tpublic void run() {\r\n\t\tfinish();\r\n\t}\r\n}<\/pre>\n<p>Custom WebView class. You can adjust how far and how fast finger hat to be tripped to make gesture effective.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\/\/custom webview\r\npublic class nfWebView extends WebView  {\r\n\tContext context;\r\n\tGestureDetector gd;\r\n\tint gesture_stx,gesture_sty;\r\n    private Handler notifyback_handler;\r\n    private Runnable notifyback_listener;\r\n\r\n\tpublic nfWebView(Context context) {\r\n\t    super(context);\r\n\t    this.context = context;\r\n\t\tgd = new GestureDetector(context, onGestureListener);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic boolean onTouchEvent(MotionEvent event) {\r\n\t\treturn (gd.onTouchEvent(event) || super.onTouchEvent(event));\r\n\t}\r\n\r\n    public void SetNotifyBackHandler(Handler _handler, Runnable _listener)\r\n    {\r\n        notifyback_handler = _handler;\r\n        notifyback_listener = _listener;\r\n    }\r\n    public void CallNotifyBackTakenHandler()\r\n    {\r\n    \tnotifyback_handler.post(notifyback_listener);\r\n    }\r\n\r\n    private final SimpleOnGestureListener onGestureListener = new SimpleOnGestureListener() {\r\n    \t@Override\r\n    \tpublic boolean onDoubleTap(MotionEvent e) {\r\n    \t\treturn super.onDoubleTap(e);\r\n    \t}\r\n    \t@Override\r\n\t\tpublic boolean onDoubleTapEvent(MotionEvent e) {\r\n    \t\treturn super.onDoubleTapEvent(e);\r\n    \t}\r\n    \t@Override\r\n    \tpublic boolean onDown(MotionEvent e) {\r\n    \t\treturn super.onDown(e);\r\n    \t}\r\n    \t@Override\r\n    \tpublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {\r\n    \t\tfloat deltax,deltay,velo;\r\n    \t\tdeltax = Math.abs(e1.getRawX()-e2.getRawX());\r\n    \t\tdeltay = Math.abs(e1.getRawY()-e2.getRawY());\r\n    \t\tvelo = Math.abs(velocityX);\r\n\r\n    \t\t\/\/pref_browser_gesturevelo is how fast finger moves.\r\n    \t\t\/\/pref_browser_gesturevelo set to 350 as default in my app\r\n    \t\tif (deltax &gt; 200 &amp;&amp; deltay &lt; 90 &amp;&amp; velo &gt; pref_browser_gesturevelo) {\r\n    \t\t\tif (e1.getRawX() &gt; e2.getRawX()) {\r\n\t\t\t\t\tif (canGoForward()){\r\n\t\t\t\t\t\t\/\/Gesture : move forward\r\n\t\t\t\t\t\tgoForward();\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse{\r\n\t\t\t\t\t\t\/\/Gesture : no more forward history\r\n    \t\t\t\t}\r\n    \t\t\t} else if(e1.getRawX() &lt; e2.getRawX()){\r\n\t\t\t\t\tif (canGoBack()){\r\n\t\t\t\t\t\t\/\/Gesture : go back\r\n   \t\t\t\t\t\tgoBack();\r\n   \t\t\t\t\t}\r\n   \t\t\t\t\telse{\r\n   \t\t\t\t\t\t\/\/Gesture : no more backward history, end browser\r\n    \t\t\t\t\tCallNotifyBackTakenHandler();\r\n   \t\t\t\t\t}\r\n    \t\t\t}\r\n    \t\t}\r\n    \t\treturn super.onFling(e1, e2, velocityX, velocityY);\r\n    \t}\r\n    \t@Override\r\n    \tpublic void onLongPress(MotionEvent e) {\r\n    \t\tsuper.onLongPress(e);\r\n    \t}\r\n    \t@Override\r\n    \tpublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {\r\n    \t\treturn super.onScroll(e1, e2, distanceX, distanceY);\r\n    \t}\r\n    \t@Override\r\n    \tpublic void onShowPress(MotionEvent e) {\r\n    \t\tsuper.onShowPress(e);\r\n    \t}\r\n    \t@Override\r\n    \tpublic boolean onSingleTapConfirmed(MotionEvent e) {\r\n    \t\treturn super.onSingleTapConfirmed(e);\r\n    \t}\r\n    \t@Override\r\n    \tpublic boolean onSingleTapUp(MotionEvent e) {\r\n    \t\treturn super.onSingleTapUp(e);\r\n    \t}\r\n    };\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>It is easy to add Web functionality to Android app using WebView. It is hard to customize contents shown inside webview, but you can customize UIs. This time, I&#8217;m going to show how to use gesture, swiping finger left \/ right to go back \/ forward in webview history. GestureDetector class is used for gesture processing. By using this class, not only left \/ right swipe but also double tap or long hold can be assigned to some functions. Be careful not to override too much of \u00a0browser functions. Use WebView class as base, and create custom WebView class to handle gesture. In sample code below, swiping finger left to &#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[330],"tags":[468,466,467,470,469],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3pJyQ-Ay","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/posts\/2266"}],"collection":[{"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/comments?post=2266"}],"version-history":[{"count":1,"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/posts\/2266\/revisions"}],"predecessor-version":[{"id":2267,"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/posts\/2266\/revisions\/2267"}],"wp:attachment":[{"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/media?parent=2266"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/categories?post=2266"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/programresource.net\/en\/wp-json\/wp\/v2\/tags?post=2266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}