在webview中禁用滚动?

时间:2010-03-27 02:27:22

标签: android android-webview android-scroll android-scrollbar

到目前为止,我一直只是一名iPhone开发者,现在我决定给Android一个旋风。我在Android上无法弄清楚的是如何以编程方式阻止在WebView中滚动?

类似于iPhone预防onTouchMove事件的事情会很棒!

15 个答案:

答案 0 :(得分:167)

以下是我在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);

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

<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(...)代码以禁用webview中的所有滚动。垂直ScrollView将允许滚动WebView的内容。

答案 1 :(得分:22)

我不知道你是否仍然需要它,但这是解决方案:

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

答案 2 :(得分:20)

使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的{​​{3}},可以看到调用sourceonTouchEvent来电doDrag

答案 3 :(得分:12)

如果您的内容正确包装,则向主体添加边距详细信息将阻止滚动:

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

足够简单,代码少了很少+ bug开销:)

答案 4 :(得分:7)

在WebView上设置一个监听器:

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

答案 5 :(得分:6)

我还没有尝试过,因为我还没有遇到过这个问题,但也许你可以超越onScroll功能?

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

答案 6 :(得分:4)

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

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

禁用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>

我希望这会有所帮助;)

答案 7 :(得分:3)

要禁用滚动,请使用此

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

答案 8 :(得分:2)

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

leftmargin="0" topmargin="0"

似乎身体标签的默认边距正在机器人上应用但在iphone上被忽略

答案 9 :(得分:2)

我解决了闪烁并自动滚动:

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,以便提供更有效的控制,例如禁用/启用滑动,启用/禁用触摸,监听器,控制转换,动画,内部定义设置等等。

答案 10 :(得分:1)

如果您继承 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);
    }
    ...

答案 11 :(得分:0)

研究上述答案几乎对我有用......但我仍然有一个问题,我可以“抛弃”2.1上的观点(似乎用2.2&amp; 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);
}
}

答案 12 :(得分:-1)

//禁用所有滚动

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

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

//仅禁用水平滚动

WebView.setHorizontalScrollBarEnabled(false);
webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

//仅禁用垂直滚动

WebView.setVerticalScrollBarEnabled(false);
webview.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
       switch (action)
        {
            case (MotionEvent.ACTION_DOWN):
                /**
                 * get Y position
                 */
                start_y = event.getY();
                break;
            case (MotionEvent.ACTION_MOVE):

               /*Disable vertical scrolling*/

              if (start_y-event.getY()>THRESHOLD_VALUE || start_y- event.getY()<-THRESHOLD_VALUE)
                    return true;
              break;
        }
    }
  });

在我的情况下,阈值为20

答案 13 :(得分:-1)

这应该是完整的答案。如@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);

答案 14 :(得分:-3)

只需在 webView 上使用android:focusableInTouchMode="false"