45

私のアプリには、いくつかの線形ビュー、いくつかのテキストビュー、1つのWebビュー、次に他の線形レイアウトなどを含むScrollViewがあります。問題は、WebViewがスクロールしないことです。ScrollはScrollViewでのみリッスンします。助言がありますか??


<ScrollView >
    <TextView />
    <WebView />              <-- this does not scroll
    <TextView />
</ScrollView >
4

7 に答える 7

98

これが解決策です。オンラインで見つかりました。WebViewをサブクラス化し、このrequestDisallowInterceptTouchEvent(true);メソッドを使用してWebViewがスクロールイベントを処理できるようにします。

TouchyWebView.java

package com.mypackage.common.custom.android.widgets

public class TouchyWebView extends WebView {

    public TouchyWebView(Context context) {
        super(context);
    }

    public TouchyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TouchyWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        requestDisallowInterceptTouchEvent(true);
        return super.onTouchEvent(event);
    }          
}

そしてlayout.xmlで

<com.mypackage.common.custom.android.widgets.TouchyWebView 
                android:id="@+id/description_web"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                 />
于 2012-11-13T00:25:11.927 に答える
15

@panosが提供するソリューションは機能しますが、ScrollViewで使用すると問題が発生します。次の拡張バージョンは、その問題を解決します。

public class TouchyWebView extends WebView {

    public TouchyWebView(Context context) {
        super(context);
    }

    public TouchyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TouchyWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

     @Override
     public boolean onTouchEvent(MotionEvent event) {
         //Check is required to prevent crash
         if (MotionEventCompat.findPointerIndex(event, 0) == -1) {
         return super.onTouchEvent(event);
         }

         if (event.getPointerCount() >= 2) {
             requestDisallowInterceptTouchEvent(true);
         } else {
             requestDisallowInterceptTouchEvent(false);
         }

         return super.onTouchEvent(event);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        requestDisallowInterceptTouchEvent(true);
    }

}

さらに、TouchyWebViewに対して次の設定が必要になる場合があります。

mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);
于 2016-04-07T22:08:52.373 に答える
6

Panosソリューションは、1つの例外を除いて、私には十分です...私の固定高さ(200dp)WebViewが空であるか、大量のコンテンツをロードしている可能性があります。したがって、「それ自体」はスクロール可能である場合とそうでない場合があります。PanosソリューションはMotionEvent常にsを消費しているため、WebViewが空でユーザーがタッチWebViewしてスクロールしようとすると、スクロールWebViewせず(コンテンツがないため)、スクロール可能な親もWebView「飲み込み」を引き起こしMotionEventます。そのため、何も起こりません。if予想される動作についての小さなステートメントを追加しました。

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(computeVerticalScrollRange() > getMeasuredHeight())
        requestDisallowInterceptTouchEvent(true);
    return super.onTouchEvent(event);
}
  • WebView空で垂直スクロール不可の場合computeVerticalScrollRange() == getMeasuredHeight()
  • WebViewコンテンツがその高さよりも長い場合(スクロール可能)、computeVerticalScrollRange() > getMeasuredHeight()
于 2016-10-24T11:23:20.733 に答える
0

@Panosと@Dipendraの解決策を検討していると、スクロールビュー内のマップビューにまだいくつかの問題がありました。一貫して垂直方向にスクロールすることはなく、メソッドは非推奨になったため、scrollview内のmapviewで使用するこのトリックを実行し、うまく機能しました。これがあなたの何人かを助けることを願っています。

public class TouchyWebView extends WebView {
ViewParent mViewParent;

public TouchyWebView(Context context) {
    super(context);
}

public TouchyWebView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public TouchyWebView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public void setViewParent(@Nullable final ViewParent viewParent) { //any ViewGroup
    mViewParent = viewParent;
}


@Override
public boolean onTouchEvent(MotionEvent event) {

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (null == mViewParent) {
                getParent().requestDisallowInterceptTouchEvent(true);
            } else {
                mViewParent.requestDisallowInterceptTouchEvent(true);
            }
            break;
        case MotionEvent.ACTION_UP:
            if (null == mViewParent) {
                getParent().requestDisallowInterceptTouchEvent(false);
            } else {
                mViewParent.requestDisallowInterceptTouchEvent(false);
            }
            break;
        default:
            break;
    }
    return super.onTouchEvent(event);
}

@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    requestDisallowInterceptTouchEvent(true);


}

}

また、コントロールの設定に関する@Dipendraのアドバイスに従いました。

mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);
于 2017-11-30T07:11:10.537 に答える
0

クラスファイルに1行追加するだけです

mWebview.setNestedScrollingEnabled(true);

WebviewまたはXMLでタグを追加します

android:nestedScrollingEnabled="true"

警告:API21および21以降のみ

于 2019-05-05T08:10:39.687 に答える
0

まだ発生していますreact-native-webview、ここで追跡された問題 https://github.com/react-native-community/react-native-webview/issues/22

于 2019-06-24T07:28:36.377 に答える
-15

3つのレイアウトに変更できます。

  1. 最初のTextView-ヘッダー
  2. WebView-メインレイアウト
  3. 2番目のTextView-フッター


WebView web = (WebView) findViewById(R.id.webView);
View header = getLayoutInflater().inflate(R.layout.header_layout, null);
View footer = getLayoutInflater().inflate(R.layout.foorer_layout, null);
web.addHeaderView(headerComment);
web.addFooterView(footerComment);
于 2012-11-06T19:34:38.290 に答える