Disable scrolling in webview?

删除回忆录丶 提交于 2019-12-16 22:37:11

问题


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!


回答1:


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.




回答2:


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);



回答3:


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.




回答4:


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 :)




回答5:


Set a listener on your WebView:

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



回答6:


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



回答7:


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 ;)




回答8:


To Disable scroll use this

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



回答9:


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




回答10:


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




回答11:


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);
    }
    ...



回答12:


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



回答13:


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);



回答14:


Just use android:focusableInTouchMode="false" on your webView.



来源:https://stackoverflow.com/questions/2527899/disable-scrolling-in-webview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!