17

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

1

9 Answers 9

37

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.

5
  • But It disabled clicking action in the Webview. Any help? Commented Aug 28, 2013 at 20:15
  • @vee : Cannot resolve symbol m_downX . what is m_downX my android studio doesn't recognize that
    – Amir.KH
    Commented Apr 29, 2015 at 22:41
  • 1
    @Amir.KH its variable name. Simply add it
    – Gelldur
    Commented Jul 5, 2015 at 9:49
  • This also disables clicking in the webview for me. Commented Jul 18, 2016 at 15:07
  • @TomKincaid it does not disable clicking, this works Commented Jul 29, 2016 at 10:37
33

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);
    }
});
6
  • 7
    If i am not wrong it will disable both horizontal and vertical scrolling
    – Vipul
    Commented Jun 16, 2012 at 14:07
  • 2
    Nope - the vertical ScrollView will allow for scrolling of the WebView's vertical content. Commented Jun 16, 2012 at 14:08
  • @SBerg: Thanks for the suggestion. This solution is working fine :).. I was just wondering whether this is the only way to block horizontal scrolling.
    – SK.
    Commented Jun 18, 2012 at 9:57
  • 1
    but when I use loadDataWithBaseUrl to load html text it cuts off content horizontally. any solution ?
    – Ketan Ahir
    Commented Dec 4, 2013 at 5:39
  • 3
    Implementing the above setOnTouchListener will disable scrolling in both directions!
    – slott
    Commented May 11, 2014 at 13:14
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/

1
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());
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;

    }
}
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;

    }
}
0
 webView.setHorizontalScrollBarEnabled(false);

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

0
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
    }
}
-1
  webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);

Showcase in Android 7.1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.