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’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 browser functions.
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.
First, main activity.
private BackNotify mNotify = new BackNotify(); private Handler mNotifyHandler = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); nfWebView webview; webview = new nfWebView(this); //register handler for webview terminate notification if(mNotifyHandler == null) mNotifyHandler = new Handler(); webview.SetNotifyBackHandler(mNotifyHandler, mNotify); //add view RelativeLayout wholder = (RelativeLayout) findViewById(R.id.web); wholder.addView(webview, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,RelativeLayout.LayoutParams.FILL_PARENT)); } //called when Back gesture is done while no more backward history public class BackNotify implements Runnable { //notify from nfWebView @Override public void run() { finish(); } }
Custom WebView class. You can adjust how far and how fast finger hat to be tripped to make gesture effective.
//custom webview public class nfWebView extends WebView { Context context; GestureDetector gd; int gesture_stx,gesture_sty; private Handler notifyback_handler; private Runnable notifyback_listener; public nfWebView(Context context) { super(context); this.context = context; gd = new GestureDetector(context, onGestureListener); } @Override public boolean onTouchEvent(MotionEvent event) { return (gd.onTouchEvent(event) || super.onTouchEvent(event)); } public void SetNotifyBackHandler(Handler _handler, Runnable _listener) { notifyback_handler = _handler; notifyback_listener = _listener; } public void CallNotifyBackTakenHandler() { notifyback_handler.post(notifyback_listener); } private final SimpleOnGestureListener onGestureListener = new SimpleOnGestureListener() { @Override public boolean onDoubleTap(MotionEvent e) { return super.onDoubleTap(e); } @Override public boolean onDoubleTapEvent(MotionEvent e) { return super.onDoubleTapEvent(e); } @Override public boolean onDown(MotionEvent e) { return super.onDown(e); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) { float deltax,deltay,velo; deltax = Math.abs(e1.getRawX()-e2.getRawX()); deltay = Math.abs(e1.getRawY()-e2.getRawY()); velo = Math.abs(velocityX); //pref_browser_gesturevelo is how fast finger moves. //pref_browser_gesturevelo set to 350 as default in my app if (deltax > 200 && deltay < 90 && velo > pref_browser_gesturevelo) { if (e1.getRawX() > e2.getRawX()) { if (canGoForward()){ //Gesture : move forward goForward(); } else{ //Gesture : no more forward history } } else if(e1.getRawX() < e2.getRawX()){ if (canGoBack()){ //Gesture : go back goBack(); } else{ //Gesture : no more backward history, end browser CallNotifyBackTakenHandler(); } } } return super.onFling(e1, e2, velocityX, velocityY); } @Override public void onLongPress(MotionEvent e) { super.onLongPress(e); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return super.onScroll(e1, e2, distanceX, distanceY); } @Override public void onShowPress(MotionEvent e) { super.onShowPress(e); } @Override public boolean onSingleTapConfirmed(MotionEvent e) { return super.onSingleTapConfirmed(e); } @Override public boolean onSingleTapUp(MotionEvent e) { return super.onSingleTapUp(e); } }; }
This post is also available in: Japanese