'How to disable horizontal scrolling in Android webview
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
Solution 1:[1]
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.
Solution 2:[2]
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);
Solution 3:[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());
Solution 4:[4]
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;
}
}
Solution 5:[5]
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;
}
}
Solution 6:[6]
webView.setHorizontalScrollBarEnabled(false);
Define whether the horizontal scrollbar should be drawn or not. The scrollbar is not drawn by default.
Solution 7:[7]
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
}
}
Solution 8:[8]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | vovahost |
| Solution 2 | Leo |
| Solution 3 | Leonid Ustenko |
| Solution 4 | Community |
| Solution 5 | Satan Pandeya |
| Solution 6 | |
| Solution 7 | Diogosq |
| Solution 8 | Martin Pfeffer |

