Android 是否在webview中禁用滚动?

Android 是否在webview中禁用滚动?,android,android-webview,android-scroll,android-scrollbar,Android,Android Webview,Android Scroll,Android Scrollbar,到目前为止,我只是一名iPhone开发者,现在我决定尝试一下Android。我在Android上还没有弄明白的一点是,如何通过编程防止在WebView中滚动 类似于iPhone的防止onTouchMove事件将非常棒 我的肮脏但易于实施且运行良好的解决方案: appView = (WebView) findViewById(R.id.appView); appView.setVerticalScrollBarEnabled(false); appView.setHorizontalScroll

到目前为止,我只是一名iPhone开发者,现在我决定尝试一下Android。我在Android上还没有弄明白的一点是,如何通过编程防止在
WebView
中滚动


类似于iPhone的防止onTouchMove事件将非常棒

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

appView = (WebView) findViewById(R.id.appView); 
appView.setVerticalScrollBarEnabled(false);
appView.setHorizontalScrollBarEnabled(false);
只需将webview放在scrollview中即可。使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>


我希望这有帮助;)

在Web视图上设置侦听器:

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

我还没有尝试过这个方法,因为我还没有遇到这个问题,但是您可能会过度使用onScroll函数

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

我不知道您是否仍然需要它,但以下是解决方案:

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

研究上述答案几乎对我有用。。。但我仍然有一个问题,那就是我可以在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);
}
}

以下是我在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.setVerticalScrollBarEnabled(false);
WebView.setHorizontalScrollBarEnabled(false);
   //Only disabled the horizontal scrolling:
   webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

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

<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.setOnTouchListener(…)
代码以禁用webview中的所有滚动。垂直滚动视图允许滚动网络视图的内容。

这可能不是问题的根源,但我花了数小时试图找出为什么我在iphone上运行良好的应用程序会导致android浏览器不断弹出垂直/水平滚动条并实际移动页面。我有一个高度和宽度设置为100%的html主体标记,主体在不同的位置充满了各种各样的标记。不管我怎么做,android浏览器都会显示滚动条并稍微移动页面,特别是在快速滑动时。对我来说,在APK中不必做任何事情的解决方案是在body标签中添加以下内容:

leftmargin="0" topmargin="0"

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

如果内容正确包装,则将边距详细信息添加到body会阻止滚动,因此:

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


非常简单,而且代码+bug开销要少得多:)

如果您子类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);
    }
    ...

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

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

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

如果查看for
WebView
,可以看到
onTouchEvent
调用
doDrag
哪些调用。

要禁用滚动,请使用此选项

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

只需在您的网络视图上使用android:focusableInTouchMode=“false”。

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

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"/>

返回
行的末尾有一个额外的括号。这也会破坏HTML5画布和JavaScript触摸事件。这当然会禁用它,但我以后如何杀死侦听器以获得可复制的输入?我尝试了
event.getAction()!=MotionEvent.ACTION\u MOVE
以及
返回true
标准的“不做任何事情”情况是
返回false
,而不是
返回true
。确定。这将禁用滚动条,但不会通过拖动阻止滚动。似乎html也必须适合……如果你只为android web view设计网页,那么我建议你将网页放在表格中。宽度应类似于width=“100%”,高度应相同。因此将不再拖动。宽度=100%并不总是有效,例如:awesome。。这正是我需要的。谢谢,工作正常,但几秒钟后会导致三星i5700 spica在/system/lib/libwebcore.so.LayoutAlgorithm.SINGLE_COLUMN或webview.setOnTouchListener中崩溃?如果将webview放在滚动视图中,请将webview的android:isScrollContainer属性设置为“false”,而不是将android:scrollbars设置为“none”。这会完全禁用webview的滚动处理,并允许它根据内容进行扩展。然后,滚动将由父ScrollView单独处理。如果您需要处理
MotionEvent.ACTION\u MOVE
事件,请在
WebView
中查看我的答案。忽略
setOnTouchListener
事件上的
ACTION\u MOVE
会产生一些副作用,因此我不推荐此答案;1.快速滑动被视为页面上的
onclick
事件。2.防止页面上的元素滚动溢出,这可能是根据站点进行正确交互所必需的。3.JS
touchmove
事件@GDanger给出了正确的答案,它通过扩展
WebView
覆盖了
overScrollBy
,因为它没有其他副作用,只是防止