これまで私はiPhone開発者のみでしたが、今ではAndroidに旋風を巻き起こすことにしました。 Androidで理解できなかったのは、WebView
のスクロールをプログラムで防ぐ方法です。
IPhoneのonTouchMove
イベントの防止に似たものは素晴らしいでしょう!
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のコンテンツをスクロールできます。
まだ必要かどうかはわかりませんが、解決策は次のとおりです。
appView = (WebView) findViewById(R.id.appView);
appView.setVerticalScrollBarEnabled(false);
appView.setHorizontalScrollBarEnabled(false);
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
の source を見ると、onTouchEvent
が overScrollBy を呼び出すdoDrag
を呼び出していることがわかります。
本文にマージンの詳細を追加すると、コンテンツが適切に折り返されている場合、スクロールが防止されます。
<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">
十分に簡単で、はるかに少ないコード+バグのオーバーヘッド:)
WebViewでリスナーを設定します。
webView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return(event.getAction() == MotionEvent.ACTION_MOVE));
}
});
私はまだこの問題に遭遇していないので、これを試したことはありませんが、おそらくonScroll関数を無視できますか?
@Override
public void scrollTo(int x, int y){
super.scrollTo(0,y);
}
私の汚いが、実装が簡単でうまく機能するソリューション:
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>
これが役立つことを願っています;)
スクロールを無効にするにはこれを使用します
webView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event)
{
return (event.getAction() == MotionEvent.ACTION_MOVE);
}
});
ちらつきと自動スクロールを次の方法で解決しました。
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を拡張することをお勧めします。
これはあなたの問題の原因ではないかもしれませんが、iPhoneで正常に動作したアプリケーションがAndroidブラウザーで常に垂直/水平スクロールバーを表示し、実際にページ。高さと幅が100%に設定されたhtml bodyタグがあり、本文にはさまざまな場所のさまざまなタグがいっぱいでした。何を試しても、Androidブラウザーはスクロールバーを表示し、特に高速スワイプを行う場合にページを少し移動します。 APKで何もせずに私のために働いた解決策は、bodyタグに以下を追加することでした:
leftmargin="0" topmargin="0"
Bodyタグのデフォルトのマージンはdroidに適用されていたが、iphoneでは無視されたようです
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);
}
...
上記の答えを勉強することは私にとってはほとんどうまくいきました...
これが私の最終的な解決策です
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);
}
}