Reputation: 355
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
Upvotes: 17
Views: 48946
Reputation: 11
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
}
}
Upvotes: 0
Reputation: 286
webView.setHorizontalScrollBarEnabled(false);
Define whether the horizontal scrollbar should be drawn or not. The scrollbar is not drawn by default.
Upvotes: 0
Reputation: 15046
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());
Upvotes: 3
Reputation: 12627
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
Upvotes: -1
Reputation: 2535
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;
}
}
Upvotes: 0
Reputation: 755
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.
Upvotes: 37
Reputation: 489
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;
}
}
Upvotes: 0
Reputation: 1433
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);
Upvotes: 3
Reputation: 14600
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);
}
});
Upvotes: 33