2012-11-06 147 views
23

在我的應用程序中,我有一個ScrollView,它包含一些linearviews,一些textviews和一個Webview,然後其他線性佈局等。問題是WebView不滾動。 Scroll只在ScrollView上偵聽。 有什麼建議?ScrollView中的Android WebView只滾動scrollview


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

回答

63

下面是解決方案。在線找到。我已經分類了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" 
       /> 
+0

+1 ...它的工作原理。 –

+2

一旦您觸碰到「WebView」之外,就會中斷。 – theblang

+0

@mattblang再次觸摸webview,然後嘗試再次滾動它。 – Panos

-9

您可以更改成3點的佈局:

  1. 第一的TextView - 頭
  2. 的WebView - 主要佈局
  3. 二的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); 
+0

我的滾動視圖存在,因爲這些項目不適合在屏幕上。在我的例子中,我只在上面添加了一個textview,在下面添加了一個textview。但實際上還有其他的相對佈局,有圖像瀏覽,webview在中間和其他地方......所以我需要滾動視圖,所以我可以看到一切。 – Panos

+0

嘗試此[解決方案](http://stackoverflow.com/questions/9718245/webview-in-scrollview) –

+4

WebView沒有「addHeaderView」或「addFooterView」方法,ListView有這些方法。所以這不是一個解決方案。 – ismailarilik

6

由@panos作品所提供的解決方案,但與滾動型使用時,它仍然有問題。以下增強版本可以克服該問題。

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

你的解決方案'WebView'只能用兩個手指滾動,只有一個手指父母正在滾動...不那麼直觀:/ – snachmsm

2

帕諾斯的解決辦法是有一個例外夠我...我的固定高度(200dp)WebView可能爲空或可能已經裝載很多的內容。所以它可能是或者可能不是可滾動的「本身」。 Panos解決方案總是消耗MotionEvent,所以當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()
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);