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

