Android Scrollview中的Webview

Android Scrollview中的Webview,android,webview,scrollview,Android,Webview,Scrollview,我必须将WebView放入ScrollView。但在webview之前,我必须将一些视图放到同一个scrollview中。看起来是这样的: <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:id="@+id/articleDetailPageContentLayout" android:l

我必须将WebView放入ScrollView。但在webview之前,我必须将一些视图放到同一个scrollview中。看起来是这样的:

<ScrollView
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  >
<LinearLayout
    android:id="@+id/articleDetailPageContentLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
  <LinearLayout
      android:id="@+id/articleDetailRubricLine"
      android:layout_width="fill_parent"
      android:layout_height="3dip"
      android:background="@color/fashion"/>

  <ImageView
      android:id="@+id/articleDetailImageView"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:adjustViewBounds="true"
      android:scaleType="fitStart"
      android:src="@drawable/article_detail_image_test"/>

  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:padding="5dip"
      android:text="PUBLISH DATE"/>

  <WebView
      android:id="@+id/articleDetailContentView"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:background="@color/fashion"
      android:isScrollContainer="false"/>
</LinearLayout>
private final static String WEBVIEW_MIME_TYPE = "text/html";
    private final static String WEBVIEW_ENCODING = "utf-8";
String viewport = "<head><meta name=\"viewport\" content=\"target-densitydpi=device-dpi\" /></head>";
        String css = "<style type=\"text/css\">" +
            "img {width: 100%;}" +
            "</style>";
        articleContent.loadDataWithBaseURL("http://", viewport + css + articleDetail.getContent(), WEBVIEW_MIME_TYPE,
            WEBVIEW_ENCODING, "about:blank");

我正在从后端获取一些HTML信息。它没有任何身体或头部标记,只有被
或其他标记包围的数据。它还有
标签。有时图片对于当前屏幕宽度来说太宽。所以我在HTML的开头添加了一些css。因此,我将数据加载到webview,如下所示:

<ScrollView
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  >
<LinearLayout
    android:id="@+id/articleDetailPageContentLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
  <LinearLayout
      android:id="@+id/articleDetailRubricLine"
      android:layout_width="fill_parent"
      android:layout_height="3dip"
      android:background="@color/fashion"/>

  <ImageView
      android:id="@+id/articleDetailImageView"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:adjustViewBounds="true"
      android:scaleType="fitStart"
      android:src="@drawable/article_detail_image_test"/>

  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:padding="5dip"
      android:text="PUBLISH DATE"/>

  <WebView
      android:id="@+id/articleDetailContentView"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:background="@color/fashion"
      android:isScrollContainer="false"/>
</LinearLayout>
private final static String WEBVIEW_MIME_TYPE = "text/html";
    private final static String WEBVIEW_ENCODING = "utf-8";
String viewport = "<head><meta name=\"viewport\" content=\"target-densitydpi=device-dpi\" /></head>";
        String css = "<style type=\"text/css\">" +
            "img {width: 100%;}" +
            "</style>";
        articleContent.loadDataWithBaseURL("http://", viewport + css + articleDetail.getContent(), WEBVIEW_MIME_TYPE,
            WEBVIEW_ENCODING, "about:blank");
private final静态字符串WEBVIEW\u MIME\u TYPE=“text/html”;
私有最终静态字符串WEBVIEW_ENCODING=“utf-8”;
字符串viewport=“”;
字符串css=“”+
“img{宽度:100%;}”+
"";
articleContent.loadDataWithBaseURL(“http://”,viewport+css+articleDetail.getContent(),WEBVIEW\u MIME\u类型,
WEBVIEW_编码,“关于:空白”);
有时当页面加载时,scrollview会滚动到webview开始的位置。我不知道如何解决这个问题

此外,有时在webview内容之后会出现巨大的空白。我也不知道该怎么办

有时当我滚动时,scrollview的滚动条开始随机抽动

我知道将webview放在scrollview中是不对的,但似乎我没有其他选择。有没有人能建议一种将所有视图和所有HTML内容放置到webview的正确方法

我知道将webview放在scrollview中是不对的,但似乎我没有其他选择

是的,你需要,因为你想要的东西不能可靠地工作

但在webview之前,我必须将一些视图放到同一个scrollview中


删除
滚动视图
。将
WebView的
android:layout\u height
更改为
fill\u parent
WebView
将填满
LinearLayout
中未被其他小部件占用的所有剩余空间。

更新2014-11-13:由于Android KitKat下面描述的两种解决方案都不起作用,您需要寻找不同的方法,例如,为网络视图

更新2012-07-08:“Nobu游戏”创建了一个类,将预期行为带回Android果冻豆。在较旧的平台上使用时,它将使用hidden
setEmbeddedTitleBar()
方法,在Jelly Bean或更高版本上使用时,它将模拟相同的行为。源代码在Apache2许可证下可用

更新2012-06-30:似乎在Android 4.1 aka Jelly Bean中删除了
setEmbeddedTitleBar()
方法:-(

原始答案:

可以将
WebView
放在
ScrollView
中,它确实可以工作。我在Android 1.6设备上使用它。主要缺点是用户无法滚动“对角线”含义:如果web内容超过屏幕宽度,
ScrollView
负责在
WebView
进行垂直滚动,以进行水平滚动。因为只有其中一个处理触摸事件,所以您可以水平滚动或垂直滚动,但不能对角滚动


此外,您还描述了一些恼人的问题(例如,加载比上一个小的内容时,垂直空间变空)。我在GoodNews中找到了所有这些问题的解决方法,但现在记不起来了,因为我找到了更好的解决方案:

如果您只将
WebView
放入
ScrollView
以将控件置于web内容之上,并且您可以只支持Android 2及以上版本,那么您可以使用
WebView
的隐藏内部
setEmbeddedTitleBar()
方法。它已在API级别5中引入,并且(意外地?)只在一个版本中公开(我想是3.0)

此方法允许您将布局嵌入将放置在web内容上方的
WebView
。垂直滚动时,此布局将在屏幕上滚动,但水平滚动时,此布局将保持在相同的水平位置

由于此方法不是由API导出的,您需要使用Java反射来调用它。我建议按如下方式派生一个新类:

public final class WebViewWithTitle extends ExtendedWebView {
    private static final String LOG_TAG = "WebViewWithTitle";
    private Method setEmbeddedTitleBarMethod = null;

    public WebViewWithTitle(Context context) {
        super(context);
        init();
    }

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

    private void init() {
        try {
            setEmbeddedTitleBarMethod = WebView.class.getMethod("setEmbeddedTitleBar", View.class);
        } catch (Exception ex) {
            Log.e(LOG_TAG, "could not find setEmbeddedTitleBar", ex);
        }
    }

    public void setTitle(View view) {
        if (setEmbeddedTitleBarMethod != null) {
            try {
                setEmbeddedTitleBarMethod.invoke(this, view);
            } catch (Exception ex) {
                Log.e(LOG_TAG, "failed to call setEmbeddedTitleBar", ex);
            }
        }
    }

    public void setTitle(int resId) {
        setTitle(inflate(getContext(), resId, null));
    }
}
然后在布局文件中,可以使用

<com.mycompany.widget.WebViewWithTitle
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />


在代码的其他地方,您可以调用
setTitle()
方法,将布局ID嵌入
WebView

下面是WebView的实现,其中包含另一个顶部的“标题栏”视图

外观:

红色条+3个按钮是一个“标题栏”,下面是web视图,所有按钮都被滚动并剪切在一个矩形中


它干净、简洁,从API 8到16以及更高版本都可以使用(只需稍加努力,它也可以在API上使用谢谢你的提问,@dmitry! 也非常感谢@sven的回答

但是我希望对于需要将WebView放在ScrollView中的情况有一个解决方法。正如sven正确地注意到的,主要问题是scroll view截取了所有可用于垂直滚动的触摸事件。因此,解决方法很明显-扩展scroll view并覆盖
ViewGroup.onInterceptTouchEvent(MotionEvent e)
方法,使滚动视图能够容忍其子视图:

  • 处理可用于垂直滚动的所有触摸事件
  • 将它们全部分派到子视图
  • 仅使用垂直滚动截获事件(dx=0,dy>0)
  • 当然,这个解决方案只能与适当的布局结合使用。 我做了一个能说明主要思想的布局示例

        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <com.rus1f1kat0r.view.TolerantScrollView
            android:id="@+id/scrollView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true" >
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content" 
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/textView1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Large Text"
                    android:textAppearance="?android:attr/textAppearanceLarge" />
    
                <TextView
                    android:id="@+id/textView2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Large Text"
                    android:textAppearance="?android:attr/textAppearanceLarge" />
    
                <WebView
                    android:id="@+id/webView1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
    
                <TextView
                    android:id="@+id/textView3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Medium Text"
                    android:textAppearance="?android:attr/textAppearanceMedium" />
    
               <TextView
                   android:id="@+id/textView4"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:text="Medium Text"
                   android:textAppearance="?android:attr/textAppearanceMedium" />
    
            </LinearLayout>
        </com.rus1f1kat0r.view.TolerantScrollView>
    </RelativeLayout>
    
    
    
    因此,主要思想本身就是通过putt避免垂直滚动冲突
    android:descendantFocusability="blocksDescendants"
    
    webView.clearView();
    mNewsContent.requestLayout();
    
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent" >
    
      <com.project.ObservableWebView
          android:id="@+id/post_web_view"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="#fff" />
    
      <LinearLayout
          android:id="@+id/post_header"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="#fff"
          android:orientation="vertical"
          android:paddingLeft="@dimen/common_ui_space"
          android:paddingRight="@dimen/common_ui_space"
          android:paddingTop="@dimen/common_ui_space" >
    
          ////some stuff
    
        </LinearLayout>
    
    </FrameLayout>
    
    @Override
    public void onScroll(int l, int t, int oldl, int oldt) {
        if (t < mTitleLayout.getHeight()) {
            ViewHelper.setTranslationY(mTitleLayout, -t);
        } else if (oldt < mTitleLayout.getHeight()) {
            ViewHelper.setTranslationY(mTitleLayout, -mTitleLayout.getHeight());
        }
    }
    
    v.getViewTreeObserver().addOnGlobalLayoutListener(
        new OnGlobalLayoutListener() {
            @SuppressWarnings("deprecation")
            @SuppressLint("NewApi")
            @Override
            public void onGlobalLayout() {
                if (mTitleLayout.getHeight() != 0) {
                    if (Build.VERSION.SDK_INT >= 16)
                        v.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    else
                        v.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }
    
                    mWebView.loadDataWithBaseURL(null, "<div style=\"padding-top: " 
                      + mTitleLayout.getHeight() / dp + "px\">" + mPost.getContent() 
                      + "</div>", "text/html", "UTF8", null);
            }
    });