16

I want to have only vertical scrolling in my webview and don't want any horizontal scrolling.

webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

This helped me to solve the scrolling issue.

But using this made my webview looking wierd. Height of all the edit text squeezed (Vertically) and is looking bad.

  • Is there any other way I can disable horizontal scrolling from client side?

  • Using SINGLE_COLUMN how can we avoid issue with webview height changes? I want the vertical look and feel to be same as what it used to be without SINGLE_COLUMN

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
SK.
  • 335
  • 1
  • 2
  • 9
  • best answer here http://stackoverflow.com/questions/8635498/any-way-to-stop-webview-built-in-scrolling/24182524#24182524 – Zar E Ahmer Jun 12 '14 at 10:49

9 Answers9

35

Here is how I disable horizontal scrolling only for a webview.

webView.setHorizontalScrollBarEnabled(false);
webView.setOnTouchListener(new View.OnTouchListener() {
    float m_downX;
    public boolean onTouch(View v, MotionEvent event) {

        if (event.getPointerCount() > 1) {
            //Multi touch detected
            return true;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                // save the x
                m_downX = event.getX();
                break;
            }
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP: {
                // set x so that it doesn't move
                event.setLocation(m_downX, event.getY());
                break;
            }

        }
        return false;
    }
});

Basically intercept the touch event and don't allow the x value to change. This allows the webview to scroll vertically but not horizontally. Do it for y if you want the opposite.

vovahost
  • 34,185
  • 17
  • 113
  • 116
vee
  • 720
  • 7
  • 8
32

This is a hack, but one that has worked for me successfully in the past. Surround your WebView in a vertically oriented ScrollView:

<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical"    >
  <WebView
    android:id="@+id/mywebview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />
</ScrollView>

and then disable all scrolling in your WebView.

To disable your WebView's scrolling, you can use this code:

 // disable scroll on touch
webview.setOnTouchListener(new View.OnTouchListener() {

    public boolean onTouch(View v, MotionEvent event) {
      return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
});
SBerg413
  • 14,515
  • 6
  • 62
  • 88
3

I just tried this and it worked like a charm, I didn't know it's this simple, just one line:

mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

Source: http://sharecoding.wordpress.com/2012/02/16/programmatically-disable-scroll-function-on-android-webview/

Leo
  • 1,433
  • 23
  • 40
  • 3
    The algorithm is now deprecated: http://developer.android.com/reference/android/webkit/WebSettings.LayoutAlgorithm.html – Luke Vo Dec 02 '13 at 05:14
3

Solution based on @vee answer, but more convenient:

public class WebViewTouchListener implements View.OnTouchListener {
    private float downX;

    @Override
    public boolean onTouch(final View v, final MotionEvent event) {
        if (event.getPointerCount() > 1) {
            //multi touch
            return true;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                // set x so that it doesn't move
                event.setLocation(downX, event.getY());
                break;
        }
        return false;
    }
}

And just use it with a WebView:

 webView.setHorizontalScrollBarEnabled(false);
 webView.setOnTouchListener(new WebViewTouchListener());
Leo DroidCoder
  • 14,527
  • 4
  • 62
  • 54
0

Following the answer by vee, here is a vertical-only WebView class. You can use it as a view element inside xml to keep your code cleaner.

package com.yourpackage.views;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebView;

/**
 * custom {@link WebView} which only scrolls vertically but not horizontally
 */
public class VerticalScrollWebview extends WebView implements View.OnTouchListener {

    // the initial touch points x coordinate
    private float touchDownX;

    public VerticalScrollWebview(Context context) {
        super(context);

        // make vertically scrollable only
        makeVerticalScrollOnly();
    }

    public VerticalScrollWebview(Context context, AttributeSet attrs) {
        super(context, attrs);

        // make vertically scrollable only
        makeVerticalScrollOnly();
    }

    public VerticalScrollWebview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        // make vertically scrollable only
        makeVerticalScrollOnly();
    }

    /**
     * make this {@link WebView} vertically scroll only
     */
    private void makeVerticalScrollOnly() {
        // set onTouchListener for vertical scroll only
        setOnTouchListener(this);

        // hide horizontal scroll bar
        setHorizontalScrollBarEnabled(false);
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {

        // multitouch is ignored
        if (motionEvent.getPointerCount() > 1) {
            return true;
        }

        // handle x coordinate on single touch events
        switch (motionEvent.getAction()) {
            // save the x coordinate on touch down
            case MotionEvent.ACTION_DOWN:
                touchDownX = motionEvent.getX();
                break;

            // reset the x coordinate on each other touch action, so it doesn't move
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                motionEvent.setLocation(touchDownX, motionEvent.getY());
                break;

        }

        // let the super view handle the update
        return false;

    }
}
Community
  • 1
  • 1
gtRfnkN
  • 489
  • 7
  • 19
0

I know its late but i hope it will help someone, please use the class mentioned below in-order to disable horizontal scroll.

public class CustomWebView extends WebView implements View.OnTouchListener {

    // the initial touch points x coordinate
    private float touchDownX;
    private OnScrollChangedCallback mOnScrollChangedCallback;

    public CustomWebView(final Context context) {
        super(context);

        // make vertically scrollable only
        makeVerticalScrollOnly();
    }

    public CustomWebView(final Context context, final AttributeSet attrs) {
        super(context, attrs);

        // make vertically scrollable only
        makeVerticalScrollOnly();
    }

    public CustomWebView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);

        // make vertically scrollable only
        makeVerticalScrollOnly();
    }

    @Override
    protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t);
    }

    public OnScrollChangedCallback getOnScrollChangedCallback() {
        return mOnScrollChangedCallback;
    }

    public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback) {
        mOnScrollChangedCallback = onScrollChangedCallback;
    }

    /**
     * Impliment in the activity/fragment/view that you want to listen to the webview
     */
    public static interface OnScrollChangedCallback {
        public void onScroll(int l, int t);
    }

    /**
     * make this {@link WebView} vertically scroll only
     */
    private void makeVerticalScrollOnly() {
        // set onTouchListener for vertical scroll only
        setOnTouchListener(this);

        // hide horizontal scroll bar
        setHorizontalScrollBarEnabled(false);
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {

        // multitouch is ignored
        if (motionEvent.getPointerCount() > 1) {
            return true;
        }

        // handle x coordinate on single touch events
        switch (motionEvent.getAction()) {
            // save the x coordinate on touch down
            case MotionEvent.ACTION_DOWN:
                touchDownX = motionEvent.getX();
                break;

            // reset the x coordinate on each other touch action, so it doesn't move
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                motionEvent.setLocation(touchDownX, motionEvent.getY());
                break;

        }

        // let the super view handle the update
        return false;

    }
}
Satan Pandeya
  • 3,747
  • 4
  • 27
  • 53
Zubair Rehman
  • 2,335
  • 2
  • 20
  • 25
0
 webView.setHorizontalScrollBarEnabled(false);

Define whether the horizontal scrollbar should be drawn or not. The scrollbar is not drawn by default.

That's Enam
  • 286
  • 2
  • 3
  • 16
0

Solution with kotlin extension approuch

import android.view.MotionEvent
import android.view.View
import android.webkit.WebView


fun WebView.disableHorizontalScroll() {
    isHorizontalScrollBarEnabled = false
    setOnTouchListener(WebViewTouchListener())
}

private class WebViewTouchListener : View.OnTouchListener {
    private var downX = 0f
    override fun onTouch(v: View?, event: MotionEvent): Boolean {
        if (event.pointerCount > 1) {
            //multi touch
            return true
        }
        when (event.action) {
            MotionEvent.ACTION_DOWN -> downX = event.x
            MotionEvent.ACTION_MOVE, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> event.setLocation(downX, event.y)
        }
        return false
    }
}
Diogosq
  • 11
  • 3
-1
  webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);

Showcase in Android 7.1

Martin Pfeffer
  • 12,471
  • 9
  • 59
  • 68