web-dev-qa-db-ja.com

WebViewでスクロールを無効にしますか?

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

IPhoneのonTouchMoveイベントの防止に似たものは素晴らしいでしょう!

81
Jake Sankey

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

またはsingle column layoutを使用して試すこともできますが、これは単純なページでのみ機能し、水平スクロールを無効にします。

   //Only disabled the horizontal scrolling:
   webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

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="fill_parent"
    Android:layout_height="fill_parent"
    Android:scrollbars="none" />
</ScrollView>

そしてセット

webview.setScrollContainer(false);

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

169
peceps

まだ必要かどうかはわかりませんが、解決策は次のとおりです。

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

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

WebViewsource を見ると、onTouchEventoverScrollBy を呼び出すdoDragを呼び出していることがわかります。

20
GDanger

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

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

十分に簡単で、はるかに少ないコード+バグのオーバーヘッド:)

13
Auri Rahimzadeh

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

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

私はまだこの問題に遭遇していないので、これを試したことはありませんが、おそらくonScroll関数を無視できますか?

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

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

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

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

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

これが役立つことを願っています;)

4
user289463

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

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

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

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を拡張することをお勧めします。

2
Abhinav Saxena

これはあなたの問題の原因ではないかもしれませんが、iPhoneで正常に動作したアプリケーションがAndroidブラウザーで常に垂直/水平スクロールバーを表示し、実際にページ。高さと幅が100%に設定されたhtml bodyタグがあり、本文にはさまざまな場所のさまざまなタグがいっぱいでした。何を試しても、Androidブラウザーはスクロールバーを表示し、特に高速スワイプを行う場合にページを少し移動します。 APKで何もせずに私のために働いた解決策は、bodyタグに以下を追加することでした:

leftmargin="0" topmargin="0"

Bodyタグのデフォルトのマージンはdroidに適用されていたが、iphoneでは無視されたようです

2

subclass Webviewの場合、onTouchEventをオーバーライドして、スクロールをトリガーするmove-eventsを除外できます。

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
mischka

上記の答えを勉強することは私にとってはほとんどうまくいきました...

これが私の最終的な解決策です

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
SteelBytes