禁用 webview 中的滚动?

发布于 2024-08-26 22:59:10 字数 159 浏览 12 评论 0原文

到目前为止,我只是一名 iPhone 开发人员,现在我决定尝试一下 Android。我在 Android 上无法弄清楚如何以编程方式防止在 WebView 中滚动?

类似于 iPhone 阻止 onTouchMove 事件的功能会很棒!

Until now I have been an iPhone developer only and now I have decided to give Android a whirl. Something I haven't been able to figure out on Android is how to programmatically prevent scrolling in a WebView?

Something similar to iPhones prevention of the onTouchMove event would be great!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

九局 2024-09-02 22:59:10

这是我在 webview 中禁用所有滚动的代码:

  // disable scroll on touch
  webview.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
  });

仅隐藏滚动条,但不禁用滚动:

WebView.setVerticalScrollBarEnabled(false);
WebView.setHorizontalScrollBarEnabled(false);

或者您可以尝试使用单列布局,但这仅适用于简单的情况页面并禁用水平滚动:

   //Only disabled the horizontal scrolling:
   webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

您还可以尝试使用垂直滚动滚动视图包装您的 webview 并禁用 webview 上的所有滚动:

<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"
    android:scrollbars="none" />
</ScrollView>

并设置

webview.setScrollContainer(false);

不要忘记添加 webview.setOnTouchListener( ...) 上面的代码禁用 web 视图中的所有滚动。垂直 ScrollView 将允许滚动 WebView 的内容。

Here is my code for disabling all scrolling in webview:

  // disable scroll on touch
  webview.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
  });

To only hide the scrollbars, but not disable scrolling:

WebView.setVerticalScrollBarEnabled(false);
WebView.setHorizontalScrollBarEnabled(false);

or you can try using single column layout but this only works with simple pages and it disables horizontal scrolling:

   //Only disabled the horizontal scrolling:
   webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

You can also try to wrap your webview with vertically scrolling scrollview and disable all scrolling on the webview:

<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"
    android:scrollbars="none" />
</ScrollView>

And set

webview.setScrollContainer(false);

Don't forget to add the webview.setOnTouchListener(...) code above to disable all scrolling in the webview. The vertical ScrollView will allow for scrolling of the WebView's content.

有深☉意 2024-09-02 22:59:10

WebView 忽略运动事件是错误的方法。如果 WebView 需要了解这些事件怎么办?

相反,子类化 WebView 并覆盖非私有滚动方法。

public class NoScrollWebView extends WebView {
    ...
    @Override
    public boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, 
                                int scrollRangeX, int scrollRangeY, int maxOverScrollX, 
                                int maxOverScrollY, boolean isTouchEvent) {
        return false;
    }

    @Override
    public void scrollTo(int x, int y) {
        // Do nothing
    }

    @Override
    public void computeScroll() {
        // Do nothing
    }
}

如果您查看 WebView 的源 你可以看到 onTouchEvent 调用 doDrag 调用 overScrollBy

Making the WebView ignore motion events is the wrong way to go about it. What if the WebView needs to hear about these events?

Instead subclass WebView and override the non-private scroll methods.

public class NoScrollWebView extends WebView {
    ...
    @Override
    public boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, 
                                int scrollRangeX, int scrollRangeY, int maxOverScrollX, 
                                int maxOverScrollY, boolean isTouchEvent) {
        return false;
    }

    @Override
    public void scrollTo(int x, int y) {
        // Do nothing
    }

    @Override
    public void computeScroll() {
        // Do nothing
    }
}

If you look at the source for WebView you can see that onTouchEvent calls doDrag which calls overScrollBy.

街角迷惘 2024-09-02 22:59:10

我不知道你是否还需要它,但解决方案如下:

appView = (WebView) findViewById(R.id.appView); 
appView.setVerticalScrollBarEnabled(false);
appView.setHorizontalScrollBarEnabled(false);

I don't know if you still need it or not, but here is the solution:

appView = (WebView) findViewById(R.id.appView); 
appView.setVerticalScrollBarEnabled(false);
appView.setHorizontalScrollBarEnabled(false);
嘿哥们儿 2024-09-02 22:59:10

如果您的内容正确换行,则将边距详细信息添加到正文将阻止滚动,如下所示:

<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">

足够简单,并且代码和错误开销要少得多:)

Adding the margin details to the body will prevent scrolling if your content properly wraps, as so:

<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">

Easy enough, and a lot less code + bug overhead :)

年少掌心 2024-09-02 22:59:10

在您的 WebView 上设置监听器:

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

Set a listener on your WebView:

webView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                return(event.getAction() == MotionEvent.ACTION_MOVE));
            }
        });
在你怀里撒娇 2024-09-02 22:59:10

我还没有尝试过这个,因为我还没有遇到这个问题,但也许你可以重写 onScroll 函数?

@Override
public void scrollTo(int x, int y){
super.scrollTo(0,y);
}

I haven't tried this as I have yet to encounter this problem, but perhaps you could overrive the onScroll function?

@Override
public void scrollTo(int x, int y){
super.scrollTo(0,y);
}
与君绝 2024-09-02 22:59:10

我的肮脏但易于实现且运行良好的解决方案:

只需将 webview 放入滚动视图中即可。使 webview 远大于可能的内容(在一维或两个维度,具体取决于要求)。 ..并根据需要设置滚动视图的滚动条。

禁用 Web 视图上的水平滚动条的示例:

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

我希望这有帮助;)

My dirty, but easy-to-implement and well working solution:

Simply put the webview inside a scrollview. Make the webview to be far too bigger than the possible content (in one or both dimensions, depending on the requirements). ..and set up the scrollview's scrollbar(s) as you wish.

Example to disable the horizontal scrollbar on a webview:

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

I hope this helps ;)

ζ澈沫 2024-09-02 22:59:10

要禁用滚动,请使用此

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

To Disable scroll use this

webView.setOnTouchListener(new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) 
    {
        return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
});
甜心 2024-09-02 22:59:10

我通过以下方式解决了闪烁和自动滚动问题:

webView.setFocusable(false);
webView.setFocusableInTouchMode(false);

但是,如果由于某种原因它仍然不起作用,只需创建一个扩展 WebView 的类,并在其上添加此方法:

// disable scroll on touch
  setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
  });

我建议扩展 WebView,以提供更有效的控制,如禁用/启用滑动、启用/禁用触摸、侦听器、控制转换、动画、内部定义设置等。

I resolved the flicker and auto-scroll by:

webView.setFocusable(false);
webView.setFocusableInTouchMode(false);

However if it still does not work for some reason, simply make a class that extends WebView, and put this method on it:

// disable scroll on touch
  setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
  });

I am suggesting to extend WebView, in order to provide more effective control, like disable/enable swipes, enable/disable touches, listeners, control transitions, animations, define settings internally so on..

眼波传意 2024-09-02 22:59:10

这可能不是你问题的根源,但我花了几个小时试图找出为什么我的应用程序在 iPhone 上运行良好,导致 Android 浏览器不断抛出垂直/水平滚动条并实际移动页面。我有一个 html body 标签,高度和宽度设置为 100%,并且主体在不同位置充满了各种标签。无论我尝试什么,Android 浏览器都会显示滚动条并稍微移动页面,特别是在快速滑动时。对我来说无需在 APK 中执行任何操作的解决方案是将以下内容添加到 body 标签:

leftmargin="0" topmargin="0"

似乎 body 标签的默认边距已应用于 droid 但在 iphone 上被忽略

This may not be the source of your problem but I have spent hours trying to track down why my application that worked fine on the iphone cause the android browser to constantly throw up the vertical/horizontal scrollbars and actually move the page. I had an html body tag with height and width set to 100%, and the body was full of various tags in different locations. No matter what I tried, the android browsers would show their scroll bars and move the page just a little bit, particularly when doing a fast swipe. The solution that worked for me without having to do anything in an APK was to add the following to the body tag:

leftmargin="0" topmargin="0"

It seems the default margins for body tag were being applied on the droid but ignored on the iphone

尘曦 2024-09-02 22:59:10

如果您子类化 Webview,则只需重写 onTouchEvent 即可过滤掉触发滚动的移动事件。

public class SubWebView extends WebView {

    @Override
    public boolean onTouchEvent (MotionEvent ev)    {
        if(ev.getAction() == MotionEvent.ACTION_MOVE) {
            postInvalidate();
            return true;
        }
        return super.onTouchEvent(ev);
    }
    ...

If you subclass Webview, you can simply override onTouchEvent to filter out the move-events that trigger scrolling.

public class SubWebView extends WebView {

    @Override
    public boolean onTouchEvent (MotionEvent ev)    {
        if(ev.getAction() == MotionEvent.ACTION_MOVE) {
            postInvalidate();
            return true;
        }
        return super.onTouchEvent(ev);
    }
    ...
手心的海 2024-09-02 22:59:10

研究上面的答案几乎对我有用......但我仍然有一个问题,我可以“抛出”2.1 上的视图(似乎已在 2.2 和 2.3 中修复)。

这是我的最终解决方案

public class MyWebView extends WebView
{
private boolean bAllowScroll = true;
@SuppressWarnings("unused") // it is used, just java is dumb
private long downtime;

public MyWebView(Context context, AttributeSet attrs)
{
    super(context, attrs);
}

public void setAllowScroll(int allowScroll)
{
    bAllowScroll = allowScroll!=0;
    if (!bAllowScroll)
        super.scrollTo(0,0);
    setHorizontalScrollBarEnabled(bAllowScroll);
    setVerticalScrollBarEnabled(bAllowScroll);
}

@Override
public boolean onTouchEvent(MotionEvent ev) 
{
    switch (ev.getAction())
    {
    case MotionEvent.ACTION_DOWN:
        if (!bAllowScroll)
            downtime = ev.getEventTime();
        break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
        if (!bAllowScroll)
        {
            try {
                Field fmNumSamples = ev.getClass().getDeclaredField("mNumSamples");
                fmNumSamples.setAccessible(true);
                Field fmTimeSamples = ev.getClass().getDeclaredField("mTimeSamples");
                fmTimeSamples.setAccessible(true);
                long newTimeSamples[] = new long[fmNumSamples.getInt(ev)];
                newTimeSamples[0] = ev.getEventTime()+250;
                fmTimeSamples.set(ev,newTimeSamples);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        break;
    }
    return super.onTouchEvent(ev);
}

@Override
public void flingScroll(int vx, int vy)
{
    if (bAllowScroll)
        super.flingScroll(vx,vy);
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt)
{
    if (bAllowScroll)
        super.onScrollChanged(l, t, oldl, oldt);
    else if (l!=0 || t!=0)
        super.scrollTo(0,0);
}

@Override
public void scrollTo(int x, int y)
{
    if (bAllowScroll)
        super.scrollTo(x,y);
}

@Override
public void scrollBy(int x, int y)
{
    if (bAllowScroll)
        super.scrollBy(x,y);
}
}

studying the above answers almost worked for me ... but I still had a problem that I could 'fling' the view on 2.1 (seemed to be fixed with 2.2 & 2.3).

here is my final solution

public class MyWebView extends WebView
{
private boolean bAllowScroll = true;
@SuppressWarnings("unused") // it is used, just java is dumb
private long downtime;

public MyWebView(Context context, AttributeSet attrs)
{
    super(context, attrs);
}

public void setAllowScroll(int allowScroll)
{
    bAllowScroll = allowScroll!=0;
    if (!bAllowScroll)
        super.scrollTo(0,0);
    setHorizontalScrollBarEnabled(bAllowScroll);
    setVerticalScrollBarEnabled(bAllowScroll);
}

@Override
public boolean onTouchEvent(MotionEvent ev) 
{
    switch (ev.getAction())
    {
    case MotionEvent.ACTION_DOWN:
        if (!bAllowScroll)
            downtime = ev.getEventTime();
        break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
        if (!bAllowScroll)
        {
            try {
                Field fmNumSamples = ev.getClass().getDeclaredField("mNumSamples");
                fmNumSamples.setAccessible(true);
                Field fmTimeSamples = ev.getClass().getDeclaredField("mTimeSamples");
                fmTimeSamples.setAccessible(true);
                long newTimeSamples[] = new long[fmNumSamples.getInt(ev)];
                newTimeSamples[0] = ev.getEventTime()+250;
                fmTimeSamples.set(ev,newTimeSamples);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        break;
    }
    return super.onTouchEvent(ev);
}

@Override
public void flingScroll(int vx, int vy)
{
    if (bAllowScroll)
        super.flingScroll(vx,vy);
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt)
{
    if (bAllowScroll)
        super.onScrollChanged(l, t, oldl, oldt);
    else if (l!=0 || t!=0)
        super.scrollTo(0,0);
}

@Override
public void scrollTo(int x, int y)
{
    if (bAllowScroll)
        super.scrollTo(x,y);
}

@Override
public void scrollBy(int x, int y)
{
    if (bAllowScroll)
        super.scrollBy(x,y);
}
}
你的背包 2024-09-02 22:59:10

这应该是完整的答案。正如@GDanger 建议的那样。
扩展 WebView 以覆盖滚动方法并将自定义 WebView 嵌入到布局 xml 中。

public class ScrollDisabledWebView extends WebView {

    private boolean scrollEnabled = false;

    public ScrollDisabledWebView(Context context) {
        super(context);
        initView(context);
    }

    public ScrollDisabledWebView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        initView(context);
    }
    // this is important. Otherwise it throws Binary Inflate Exception.
    private void initView(Context context) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    }

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,
                                   int scrollRangeX, int scrollRangeY, int maxOverScrollX,
                                   int maxOverScrollY, boolean isTouchEvent) {
        if (scrollEnabled) {
            return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,
                    scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
        }
        return false;
    }

    @Override
    public void scrollTo(int x, int y) {
        if (scrollEnabled) {
            super.scrollTo(x, y);
        }
    }

    @Override
    public void computeScroll() {
        if (scrollEnabled) {
            super.computeScroll();
        }
    }
}

然后嵌入布局文件,如下所示。

<com.sample.apps.ScrollDisabledWebView
    android:id="@+id/webView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    tools:context="com.sample.apps.HomeActivity"/>

然后在活动中,也使用一些附加方法来禁用滚动条。

ScrollDisabledWebView webView = (ScrollDisabledWebView) findViewById(R.id.webView);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);

This should be the complete answer. As suggested by @GDanger .
Extend WebView to override the scroll methods and embed the custom webview within layout xml.

public class ScrollDisabledWebView extends WebView {

    private boolean scrollEnabled = false;

    public ScrollDisabledWebView(Context context) {
        super(context);
        initView(context);
    }

    public ScrollDisabledWebView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        initView(context);
    }
    // this is important. Otherwise it throws Binary Inflate Exception.
    private void initView(Context context) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    }

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,
                                   int scrollRangeX, int scrollRangeY, int maxOverScrollX,
                                   int maxOverScrollY, boolean isTouchEvent) {
        if (scrollEnabled) {
            return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,
                    scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
        }
        return false;
    }

    @Override
    public void scrollTo(int x, int y) {
        if (scrollEnabled) {
            super.scrollTo(x, y);
        }
    }

    @Override
    public void computeScroll() {
        if (scrollEnabled) {
            super.computeScroll();
        }
    }
}

And then embed in layout file as follows

<com.sample.apps.ScrollDisabledWebView
    android:id="@+id/webView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    tools:context="com.sample.apps.HomeActivity"/>

Then in the Activity, use some additional methods for disabling scrollbars too.

ScrollDisabledWebView webView = (ScrollDisabledWebView) findViewById(R.id.webView);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文