Adam
Adam

Reputation: 33126

WebView in ScrollView prevents all scrolling

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>

Upvotes: 2

Views: 4070

Answers (2)

Dmytro Danylyk
Dmytro Danylyk

Reputation: 19788

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;
    }


}

Upvotes: 5

CommonsWare
CommonsWare

Reputation: 1006744

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.

Upvotes: 1

Related Questions