ScrollView中的Android WebView仅滚动scrollview

时间:2012-11-06 19:28:57

标签: android webview scroll scrollview

在我的应用程序中,我有一个ScrollView,其中包含一些线性视图,一些textview和一个Webview,然后是其他线性布局等。问题是WebView不会滚动。 Scroll仅侦听ScrollView。 有什么建议??


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

7 个答案:

答案 0 :(得分:76)

这是解决方案。在网上找到。我已经将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"
                 />

答案 1 :(得分:11)

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

答案 2 :(得分:4)

Panos解决方案对我来说已经足够了,只有一个例外......我的固定高度(200dp)WebView可能是空的,或者可能已经加载了很多内容。所以它可能是也可能不是可滚动的&#34;本身&#34;。 Panos解决方案总是消耗MotionEvent,所以当WebView为空且用户触摸WebView并尝试滚动时,WebView将不会滚动(因为没有内容)也是可滚动的父级,导致WebView&#34;吞下&#34; MotionEvent - 所以没有任何反应。我已为预期行为添加了小if语句:

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(computeVerticalScrollRange() > getMeasuredHeight())
        requestDisallowInterceptTouchEvent(true);
    return super.onTouchEvent(event);
}
  • WebView为空且不可垂直滚动时computeVerticalScrollRange() == getMeasuredHeight()
  • WebView的内容长于其高度(可滚动)时,computeVerticalScrollRange() > getMeasuredHeight()

答案 3 :(得分:1)

只需在类文件中添加一行

mWebview.setNestedScrollingEnabled(true);

或以XML添加Webview标记

android:nestedScrollingEnabled="true"
  

警告:仅适用于API 21和21 +

答案 4 :(得分:0)

解决@Panos和@Dipendra的解决方案我仍然在scrollview中遇到了mapview的一些问题。它不会一直垂直滚动,并且方法已被弃用,所以我在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);

答案 5 :(得分:0)

仍然发生在remove中,问题在此处跟踪 https://github.com/react-native-community/react-native-webview/issues/22

答案 6 :(得分:-11)

您可以更改为3种布局:

  1. 第一个TextView - 标题
  2. WebView - 主要布局
  3. 第二个TextView - 页脚

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