74

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

Нечто похожее на предотвращение iPhone onTouchMove будет здорово!

ответ

159

Вот мой код для отключить все прокрутки в 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 вертикально прокрутку scrollview и отключить прокрутку в веб-обзоре:

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

+0

отлично работает, но через несколько секунд вызывает сбой на Samsung i5700 spica в /system/lib/libwebcore.so. – Lukas

+0

LayoutAlgorithm.SINGLE_COLUMN или webview.setOnTouchListener? – peceps

+0

Я начинаю другую деятельность в onTouchListener, так что, пожалуйста, скажите мне, как распустить вертикальный свиток.? – Noby

4

Мой грязный, но простой в реализации и хорошо работает решение:

Проще говоря WebView внутри Scrollview. Сделайте веб-просмотр слишком большим, чем возможный контент (в одном или обоих измерениях, в зависимости от требований). ..и настройте полосу прокрутки 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> 

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

+0

yep, но тогда размер прокрутки не будет слишком большим с большим количеством свободного пространства внизу? –

+1

Что делать, если ширина содержимого будет 1001dp? – Waltsu

7

Установите приемник на своем WebView:

// 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)); 
      } 
     }); 
+2

В конце строки 'return' есть дополнительная скобка. Кроме того, это разрывает возможности HTML5 и события касания JavaScript. –

+0

Это, безусловно, отключает его, но как я могу убить слушателя позже на поменять вход? Я попробовал 'event.getAction()! = MotionEvent.ACTION_MOVE', а также' return true' – CQM

6

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

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

Это то, что мы называем в Индии Jugaad ... хотя работали просто отлично – R4chi7

22

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

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

ok. это отключает полосы прокрутки, но это не предотвращает прокрутку путем перетаскивания. Кажется, что html тоже должен соответствовать ... – rdmueller

+0

Если вы разрабатываете свои веб-страницы только для просмотра веб-сайтов Android, я рекомендую сделать ваши веб-страницы в таблице. Ширина должна быть равна width = "100%" и одинаковой для высоты. так что больше не будет перетаскивания. – umar

+0

width = 100% не всегда работает, например: http://stackoverflow.com/questions/6460871/incorrect-width-in-android-webkit-browser – NoBugs

1

изучения выше ответы почти работал для меня ... но я все еще была проблема что я мог «бросить» представление на 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); 
} 
} 
+0

Для переопределения метода onScrollChanged() работает для меня. В моем случае я не могу перетащить индикатор прогресса видео и звука в WebView с помощью ответа accept. Большое спасибо! – codezjx

2

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

leftmargin="0" topmargin="0" 

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

12

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

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

достаточно легко, и гораздо меньше кода + ошибка над головой :)

+0

Блестящий! +1 для простого решения только для HTML. Иногда я хочу, макет в андроиде был так же прост, как css ... –

+0

Выглядит хорошо в Android-браузере, но, похоже, не работает в Firefox (Fennec) ... несмотря на то, что нет ничего, чтобы прокручивать до горизонтали, Firefox по-прежнему позволяет прокручивать вправо до точки, где все содержимое прокручивается с экрана. – Michael

+0

Не работает на современных WebView (Android 5 и выше) – Roel

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

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

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

Работайте как шарм! – Ernest

14

делая 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.

+1

Если вам нужно программно отключить/включить прокрутку, посмотрите на этот [gist] (https://gist.github.com/GavinDBrown/a73c53093dc2dd62aa17), который я создал. – GDanger

+1

Ваш метод работает для меня. И я вполне согласен с тобой. В моем случае я не могу перетащить индикатор прогресса видео и звука в WebView с помощью ответа accept. – codezjx

+1

Это должен быть принятый ответ, отлично работает! – 0101100101

4

Для Disbale использования свитки этого

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

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

Просто использовать android:focusableInTouchMode="false" на вашем Webview.

0

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

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

0

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

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; 

    } 
} 
Смежные вопросы