Отключить прокрутку в веб-просмотре?

До сих пор я был разработчиком iPhone, и теперь я решил дать Android завихрение. Что-то, что мне не удалось выяснить на Android, - это программно предотвратить прокрутку в WebView?

Нечто похожее на предотвращение iPhones события onTouchMove было бы здорово!

Ответ 1

Вот мой код для отключения всех прокрутки в веб-просмотре:

  // 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(...) выше, чтобы отключить всю прокрутку в веб-просмотре. Вертикальный ScrollView позволит прокручивать содержимое WebView.

Ответ 2

Я не знаю, нужна ли вам эта проблема или нет, но вот решение:

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

Ответ 3

Выполнение 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
    }
}

Если вы посмотрите source для WebView, вы увидите, что onTouchEvent вызывает doDrag, который вызывает overScrollBy.

Ответ 4

Добавление деталей поля в тело предотвратит прокрутку, если ваш контент правильно обернут, так:

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

Достаточно легко и намного меньше накладных расходов на код +:)

Ответ 5

Установите прослушиватель на веб-просмотр:

// breakingart.com: This prevents the webview being scrolled
webView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                return(event.getAction() == MotionEvent.ACTION_MOVE));
            }
        });

Ответ 6

Я не пробовал это, так как мне еще предстоит встретить эту проблему, но, возможно, вы могли бы перекрыть функцию onScroll?

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

Ответ 7

Мое грязное, но простое в использовании и хорошо работающее решение:

Просто разместите webview внутри scrollview. Сделайте веб-просмотр слишком большим, чем возможный контент (в одном или обоих измерениях, в зависимости от требований)...и настройте полосу прокрутки scrollview по своему желанию.

Пример отключения горизонтальной полосы прокрутки на веб-просмотре:

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

Я надеюсь, что это поможет;)

Ответ 8

Чтобы отобразить прокрутку, используйте

webView.setOnTouchListener(новый View.OnTouchListener() {

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

Ответ 9

Это не может быть источником вашей проблемы, но я потратил часы, пытаясь отследить, почему мое приложение, которое отлично работает на iphone, заставляет браузер android постоянно поднимать вертикальные/горизонтальные полосы прокрутки и фактически перемещать страницу. У меня был тег html body с высотой и шириной, установленный на 100%, и тело было полон различных тегов в разных местах. Независимо от того, что я пытался, браузеры Android отображали свои полосы прокрутки и немного перемещали страницу, особенно при быстром прокрутке. Решение, которое работало для меня без необходимости делать что-либо в APK, состояло в том, чтобы добавить в тег body следующее:

leftmargin="0" topmargin="0"

Кажется, что поля по умолчанию для тега тела применяются к дроиду, но игнорируются на iphone

Ответ 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);
}
}

Ответ 11

Если вы подкласс 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);
    }
    ...

Ответ 12

Я разрешил мерцание и автопрокрутку:

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

Ответ 13

//Отключить все прокрутки

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

Ответ 14

Используйте класс, указанный ниже, чтобы отключить горизонтальную прокрутку в веб-представлении.

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;

    }
}

Ответ 15

Просто используйте android:focusableInTouchMode="false" в своем веб-браузере.