私のアプリには、LinearView、TextView、One Webview、その他の線形レイアウトなどを含むScrollViewがあります。問題は、WebViewがスクロールしないことです。 ScrollはScrollViewでのみリッスンします。助言がありますか??
<ScrollView >
<TextView />
<WebView /> <-- this does not scroll
<TextView />
</ScrollView >
これが解決策です。オンラインで発見。 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"
/>
@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);
Panosソリューションは、1つの例外を除いて十分です...固定高(200dp)WebView
が空であるか、大量のコンテンツが読み込まれている可能性があります。そのため、「それ自体」でスクロールできる場合とできない場合があります。 PanosソリューションはMotionEvent
sを常に消費するため、WebView
が空で、ユーザーがWebView
をタッチしてスクロールしようとすると、WebView
はスクロールしません(ないため)コンテンツ)およびスクロール可能な親も、WebView
"swallows" MotionEvent
を引き起こす-何も起こりません。予想される動作に小さなif
ステートメントを追加しました。
_@Override
public boolean onTouchEvent(MotionEvent event) {
if(computeVerticalScrollRange() > getMeasuredHeight())
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(event);
}
_
WebView
が空で、垂直スクロールできない場合、computeVerticalScrollRange() == getMeasuredHeight()
WebView
がコンテンツの高さより長い(スクロール可能)場合、computeVerticalScrollRange() > getMeasuredHeight()
mWebview.setNestedScrollingEnabled(true);
またはXMLのWebview
タグに追加
Android:nestedScrollingEnabled="true"
警告:API 21および21+のみ
それでもreact-native-webview
、ここで追跡されている問題 https://github.com/react-native-community/react-native-webview/issues/22
@Panosと@Dipendraのソリューションを解決するために、スクロールビュー内のマップビューにまだいくつかの問題がありました。一貫して垂直にスクロールしないため、メソッドが非推奨になったため、スクロールビュー内のマップビューで使用するこのトリックを解決しました。これがあなたの一部に役立つことを願っています。
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);