2

I want to:

  1. put a fragment on screen, that contains:
    1. a WebView
    2. ...expanded to its full height
    3. embedded in a layout of fixed size above and below
    4. scroll the layout (i.e. the whole thing, including the full-height webview)

This seems impossible. I've now read 10+ different questions/answers on SO, all of them covering different critical bugs in Android WebView, but none of them covering this situation.

It seems (from reading the other questions, and following links to current unfixed bugs on the android site) that:

  1. WebView's height has always been wrong (unfixed Android 2 - 4: e.g. the height never decreases)
  2. WebView's scrolling breaks, un-breaks, re-breaks in new ways in successive Android releases (e.g: some releases ScrollView takes control, others WebView takes control, others they "fight" and you get stuttering, etc)
  3. You have to use some bizarre tweaks to ScrollView to make it do what it's supposed to do out-of-the-box. e.g. "android:fillViewport="true" (huh? isn't that exactly what "layout_height=fill_parent" is supposed to do?)

Does anyone have working code to achieve this relatively simple and common setup? I'd be interested in anything that works (except, of course "throw away your Android app and write a webapp". That might work, but would be unrealistic, sadly)

For reference (and for anyone else trying something similar) here's my layout that fills the screen, but all scrolling is disabled, for no reason I can see:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true"
>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <!-- page header -->

        <RelativeLayout
            android:id="@+id/fragment_detailspage_titletext_layout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:visibility="visible" >

            <include
                android:id="@+id/fragment_detailspage_titletext_include"
                layout="@layout/include_textheader"
                android:visibility="visible" />
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/fragment_detailspage_header_layout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/fragment_detailspage_titletext_layout"
            android:clickable="true"
            android:visibility="visible" >

            <!-- logo image -->

            <include
                android:id="@+id/fragment_detailspage_logoimageheader_include"
                layout="@layout/include_logoimageheader" />
        </RelativeLayout>

        <!-- page footer -->

        <RelativeLayout
            android:id="@+id/fragment_detailspage_footer_layout"
            android:layout_width="fill_parent"
            android:layout_height="64dp"
            android:layout_alignParentBottom="true"
            android:background="@drawable/generic_button_not_pressed"
            android:clickable="true"
            android:visibility="visible" >

            <!-- 1 buttons -->

            <include
                android:id="@+id/fragment_detailspage_bottombuttonstrip1_include"
                android:layout_width="wrap_content"
                android:layout_height="64dp"
                android:layout_centerHorizontal="true"
                layout="@layout/include_bottombuttonstrip1" />
        </RelativeLayout>

        <!-- page content -->

        <WebView
            android:id="@+id/fragment_detailspage_content_web"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_above="@id/fragment_detailspage_footer_layout"
            android:layout_below="@id/fragment_detailspage_header_layout"
            android:visibility="visible" />

    </RelativeLayout>

</ScrollView>
Adam
  • 32,900
  • 16
  • 126
  • 153
  • 1
    Did you looked at this post? http://stackoverflow.com/a/13353874/801437 – Vishal Vyas May 08 '13 at 20:23
  • "I've now read 10+ different questions/answers on SO, all of them covering different critical bugs in Android WebView, but none of them covering this situation" -- I'm pretty sure that I have answered many Android questions, indicating that putting scrollable content in a `ScrollView` rarely works well. – CommonsWare May 08 '13 at 20:26
  • 1
    +1 on CommonsWare's point, don't put scrollable views in a ScrollView. Your layout looks like it may be a bit ...over-engineered. You could attach an image to your Q of what you want your layout to look like then maybe we could help you simplify your xml and explain why you don't need the WebView in a ScrollView – Blundell May 08 '13 at 20:46
  • @VishalVyas yes, I saw that one. It makes the webview scroll, but disables the scrollview. I'm trying to do the opposite (which, from Android docs, appears to be the INTENDED default) – Adam May 08 '13 at 20:54
  • @CommonsWare - Yep, I agree it works poorly, it's a bad class. But it's used (and abused) by almost every app out there, so ... I figured there must be some decent workarounds :). Maybe there's a community-authored BetterScrollView or similar (that I haven't found yet :( ), etc. – Adam May 08 '13 at 20:55
  • "But it's used (and abused) by almost every app out there" -- I'll be stunned if more than 2% of Android apps use it. So, if that's what you mean by "almost every", OK. – CommonsWare May 08 '13 at 20:58
  • @Blundell - it's a pretty simple layout, IMHO. I've seen (and written) much more complex ones, which worked fine. If Android couldn't handle something as simple as this I'd suggest the whole layout system was "over-engineered" as you put it (use something simplistic like iOS's struts instead?) - but IME the Android layout system was *designed* for complex layouts, and usually (as noted) works great. WebView and ScrollView both seem to be Bad Citizens here. – Adam May 08 '13 at 20:59
  • @CommonsWare - Um, OK. I can only go by personal experience here - almost ever app I use has some form of Web / Scroll / custom header/footer combo. Ditto almost every app I see on a day to day basis (when researching other apps). If they're doing something different - please share it! If there's a better way, I want to do it – Adam May 08 '13 at 21:02

2 Answers2

5

Sorry for image below, but I imagine it every time, when someone want to put scrollable view inside scrollable view.

enter image description here

Please try to use CustomScrollView and override onInterceptTouchEvent:

public class CustomScrollView extends ScrollView {

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

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

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        super.onInterceptTouchEvent(e);
        return false;
    }


}
Dmytro Danylyk
  • 19,684
  • 11
  • 62
  • 68
1

almost ever app I use has some form of Web / Scroll / custom header/footer combo

Bear in mind that "Web" can be TextView instead of WebView, bear in mind that "Scroll" can be ListView instead of ScrollView, and bear in mind that "custom header/footer combo" can be implemented in HTML inside the WebView. Any of those would allow you to get out of the WebView-in-a-ScrollView scenario. Few apps will use ScrollView, and fewer still will attempt WebView in a ScrollView.

There are certainly more complicated possibilities. For example, Gmail's conversation view is a WebView with other things layered atop of it on the Z axis using a FrameLayout, where they presumably track the scroll events of the WebView to change the position of the other stuff layered atop of it (e.g., pinning the sender-and-reply-button header when you scroll to get it to the top).

You are welcome to use uiautomatorviewer to learn how this sort of stuff is implemented, if you have an Android 4.1+ device. That's how I am seeing how Gmail is pulling it off. You can't get all the details, but it gives you clues.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491