Webビューでスクロールを無効にしますか?


86

今まで私はiPhone開発者だけでしたが、今ではAndroidに旋風を巻き起こすことにしました。私がAndroidで理解できなかったのは、プログラムでスクロールを防ぐ方法WebViewです。

onTouchMoveイベントのiPhone予防に似た何かが素晴らしいでしょう!

回答:


179

Webビューですべてのスクロール無効にするための私のコードは次のとおりです。

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

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.setScrollContainer(false);

webview.setOnTouchListener(...)上記のコードを追加して、Webビューのすべてのスクロールを無効にすることを忘れないでください。垂直スクロールビューでは、WebViewのコンテンツをスクロールできます。


正常に動作しますが、数秒後に/system/lib/libwebcore.soのSamsung i5700spicaでクラッシュが発生します。
ルーカス

LayoutAlgorithm.SINGLE_COLUMNまたはwebview.setOnTouchListener?
peceps

3
WebViewをScrollViewに配置する場合は、android:scrollbarsを「none」に設定するのではなく、WebViewのandroid:isScrollContainer属性を「false」に設定します。これには、Webビューのスクロール処理を完全に無効にする効果があり、コンテンツに応じてWebビューを拡張できます。スクロールは、親のScrollViewによってのみ処理されます。
BladeCoder 2014

1
MotionEvent.ACTION_MOVEイベントを処理する必要がある場合WebViewは、以下の私の回答を参照してください。
GDanger 2014

1
イベントでを無視するACTION_MOVEと、setOnTouchListenerいくつかの副作用があるため、この回答はお勧めしません。1.クイックスワイプはonclick、ページへのイベントとしてカウントされます。2.ページ上の要素のオーバーフロースクロールを防ぎます。これは、サイトによっては適切な対話のために必要になる場合があります。3.JStouchmoveイベント。@GDangerには正解があり、他の副作用はなく、ページのスクロールを防ぐだけなので、overScrollByを拡張するWebViewことでオーバーライドしています。stackoverflow.com/a/26129301/1244574
jkasten

22

あなたがまだそれを必要とするかどうかはわかりませんが、ここに解決策があります:

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

18
OK。これによりスクロールバーが無効になりますが、ドラッグによるスクロールが妨げられることはありません。... HTMLがあまりにもフィットしなければならないようだ
rdmueller

あなたがアンドロイドウェブビューのためだけにあなたのウェブページをデザインしているなら、私はあなたのウェブページをテーブルにすることをお勧めします。幅はwidth = "100%"のようにし、高さも同じにする必要があります。したがって、ドラッグはもうありません。
umar 2011

幅= 100%とは、例えば、常に仕事をしません:stackoverflow.com/questions/6460871/...
NoBugs

素晴らしい..それは私が必要なものです。ありがとう
ピーター

21

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あなたはそれを参照することができますonTouchEvent通話doDrag呼び出しますoverScrollByを


1
プログラムでスクロールを無効/有効にする必要がある場合は、私が作成したこの要点を見てください。
GDanger 2014年

1
あなたの方法は私のために働きます。そして、私はあなたに完全に同意します。私の場合、Accept Answerを使用して、WebViewに埋め込まれたビデオとオーディオのプログレスバーをドラッグすることはできません。
codezjx 2015年

これが正解です。ただし、オーバーライドするコンストラクター全体でいくつかの調整が必要です。以下の私の完全な答えを見てください。stackoverflow.com/a/51936944/393502
Vansi 2018

13

余白の詳細を本文に追加すると、コンテンツが適切に折り返されている場合、スクロールが防止されます。

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

十分に簡単で、コードとバグのオーバーヘッドがはるかに少なくなります:)


1
鮮やかさ!単純なHTMLのみのソリューションの場合は+1。時々私が望むのは、Androidでのレイアウトがcssと同じくらい簡単だったことです...
Pritesh Desai 2013

標準のAndroidブラウザーでは見栄えがしますが、Firefox(Fennec)では機能しないようです...水平方向にスクロールするものがないにもかかわらず、Firefoxではすべてのコンテンツがスクロールしたところまで右にスクロールできます画面から。
マイケル

1
最新のWebView(Android 5以降)では機能しません
Roel 2017年

8

WebViewにリスナーを設定します。

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

3
そこのreturn行の終わりに余分な括弧があります。また、これはHTML5キャンバスとJavaScriptタッチイベントを壊します。
Rohan Singh

これは確かにそれを無効にしますが、後でリスナーを強制終了して再利用可能な入力にするにはどうすればよいですか?私も試しevent.getAction() != MotionEvent.ACTION_MOVEましたreturn true
CQM 2011

標準の「何もしない」場合はreturn false、ではありませんreturn true
マシューリード

6

私はまだこの問題に遭遇していないのでこれを試していませんが、おそらくonScroll機能を無効にすることができますか?

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

これは私たちがインドで
ジュガール

4

私の汚いが、実装が簡単でうまく機能するソリューション:

Webビューをスクロールビュー内に配置するだけです。Webビューを可能なコンテンツよりも大きくしすぎないようにします(要件に応じて、一方または両方の次元で)。..そして、必要に応じてスクロールビューのスクロールバーを設定します。

Webビューで水平スクロールバーを無効にする例:

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

これがお役に立てば幸いです;)


うん、でもスクロールサイズは大きすぎず、下部にたくさんの空白がありますか?
Rafael Sanches 2011

1
コンテンツの幅が1001dpになるとどうなりますか?
Waltsu 2014

3

ちらつきと自動スクロールを次の方法で解決しました。

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を拡張することを提案しています。


3

スクロールを無効にするには、これを使用します

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

2

これはあなたの問題の原因ではないかもしれませんが、iPhoneで正常に動作したアプリケーションがAndroidブラウザに垂直/水平スクロールバーを絶えずスローさせて実際にページを移動させる理由を突き止めるために何時間も費やしました。高さと幅を100%に設定したhtmlボディタグがあり、ボディはさまざまな場所にさまざまなタグでいっぱいでした。私が何を試しても、Androidブラウザーはスクロールバーを表示し、特に高速スワイプを行うときにページを少しだけ移動しました。APKで何もしなくてもうまくいった解決策は、bodyタグに次を追加することでした。

leftmargin="0" topmargin="0"

bodyタグのデフォルトのマージンがドロイドに適用されていたようですが、iPhoneでは無視されています


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

0

上記の答えを研究することは私にとってほとんどうまくいきました...しかし、私はまだ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);
}
}

onScrollChanged()メソッドをオーバーライドすることは私のために働きます。私の場合、Accept Answerを使用して、WebViewに埋め込まれたビデオとオーディオのプログレスバーをドラッグすることはできません。どうもありがとう!
codezjx 2015年

-1

これが完全な答えになるはずです。@GDangerによって提案されたように。WebViewを拡張して、スクロールメソッドをオーバーライドし、カスタムWebビューをレイアウト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);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.