如何在Android webview中禁用水平滚动

16

我希望我的webview只能垂直滚动,不想有水平滚动条。

webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

这个设置能够帮助我解决滚动问题。

但是使用这个设置后,我的webview看起来很奇怪。所有编辑框的高度都被压缩(纵向),并且看起来很糟糕。

  • 是否有其他方法可以从客户端禁用水平滚动条?

  • 使用SINGLE_COLUMN如何避免webview高度改变的问题? 我希望垂直的外观和感觉与没有使用'SINGLE_COLUMN'时相同


此链接中最佳答案:http://stackoverflow.com/questions/8635498/any-way-to-stop-webview-built-in-scrolling/24182524#24182524 - Zar E Ahmer
9个回答

35

这里是我如何只为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;
    }
});

基本上拦截触摸事件并不允许x值改变。这样允许webview在垂直方向上滚动,但不能在水平方向上滚动。如果你想要相反的效果,请对y进行操作。


但是它禁用了Webview中的点击操作。有什么帮助吗? - Sami Eltamawy
@vee:无法解析符号 m_downX。m_downX 是什么?我的 Android Studio 无法识别它。 - Amir.KH
1
@Amir.KH是变量名。只需将其添加即可。 - Gelldur
这也禁用了 Webview 上的点击功能。 - Tom Kincaid
@TomKincaid 这并不会禁用点击,这个是有效的。 - Nicholas Ng

32

这是一种hack方法,但在过去曾经对我起到了成功的作用。将你的WebView包含在一个垂直方向的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>

然后禁用您的 WebView 中的所有滚动。

要禁用 WebView 的滚动,您可以使用以下代码:

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

    public boolean onTouch(View v, MotionEvent event) {
      return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
});

7
如果我没错的话,它将禁用水平和垂直滚动。 - Vipul
2
不,垂直ScrollView将允许滚动WebView的垂直内容。 - SBerg413
@SBerg:感谢您的建议。这个解决方案很好用 :).. 我只是想知道是否这是阻止水平滚动的唯一方法。 - SK.
1
但是当我使用loadDataWithBaseUrl加载HTML文本时,它会水平截断内容。有什么解决办法吗? - Ketan Ahir
3
实现上述setOnTouchListener将禁用双向滚动! - slott
这对我来说防止了所有的滚动。 - Tom Kincaid

3

我刚刚尝试了这个方法,它非常有效,我不知道它如此简单,只需要一行代码:

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

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

这篇文章介绍了如何在Android WebView中编程禁用滚动功能。您可以通过设置WebView的OnTouchListener来实现此目的。具体步骤是:捕获ACTION_MOVE事件并返回true,以防止WebView响应滚动手势。


3
这个算法现已过时:http://developer.android.com/reference/android/webkit/WebSettings.LayoutAlgorithm.html - Luke Vo

3
基于 @vee 的答案,但更为方便的解决方案:
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;
    }
}

并且可以在WebView中使用:

 webView.setHorizontalScrollBarEnabled(false);
 webView.setOnTouchListener(new WebViewTouchListener());

0

虽然有点晚了,但我希望这能帮到某些人,请使用下面提到的类来禁用水平滚动。

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

vee 的回答之后,这里有一个仅限竖直的 WebView 类。你可以将其作为视图元素嵌入到 xml 中,以便保持代码的清晰整洁。

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

使用Kotlin扩展方法的解决方案

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

0
 webView.setHorizontalScrollBarEnabled(false);

定义是否应绘制水平滚动条。默认情况下不绘制滚动条。


-1
  webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);

展示 在 Android 7.1 中


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接