10

Below is my code to handle the correct behaviour of my apps actionBar/toolbar/tabBar and nestedScrollView with a ViewPager (webView) inside it. The ViewPager is basically a normal webView.

Everything works fine except my ViewPager can't be scrolled vertically. Only the NestedScrollView is being scrolled. I want the same behaviour as the Facebook app, if you scroll the newsfeed (webView) the tabBar moves the toolbar out of vision vertically.

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".ui.activity.FragmentContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    app:theme="@style/M.Toolbar"
                    app:popupTheme="@style/M.Toolbar.PopupTheme"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_scrollFlags="scroll|enterAlways"
                    >
                </android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="scrollable"
            android:visibility="gone"
            android:background="@color/background"
            app:background="@color/background"
            />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:background="@android:color/transparent"
        android:fillViewport="true"
        >

    <com.m.ui.util.EdgeScrollViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        android:visibility="visible"
        >

    </com.m.ui.util.EdgeScrollViewPager>

    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

So in order to be able to scroll my viewPager (webView) I added a new class which extends webView:

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

This solves the problem with the viewPager (webView) which becomes scrollable. BUT, the NestedScrollView becomes static and refuses to scroll the tabBar/toolbar vertically. So I am stuck with either scrolling the webView OR the tabBar-toolbar. How do I make both viewPager(webView) and NestedScrollView (tabBar/toolbar) scrollable at the same time ?

My webView

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">

    <com.m.ui.base.TouchyWebView
        android:id="@+id/web_webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        android:visibility="visible" />

    <LinearLayout
        android:id="@+id/web_loadingview"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_gravity="center">

        <ProgressBar
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:indeterminate="true"
            android:visibility="visible"
            android:layout_gravity="center"/>
    </LinearLayout>

</FrameLayout>

Regards

3 Answers 3

7

Please, try this code:

class NestedScrollWebView constructor(
        context: Context,
        attrs: AttributeSet): WebView(context, attrs), NestedScrollingChild2 {

    private var lastMotionY = 0
    private var nestedYOffset = 0
    private val scrollOffset = IntArray(2)
    private val scrollConsumed = IntArray(2)
    private val childHelper = NestedScrollingChildHelper(this)

    init {
        isNestedScrollingEnabled = true
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event == null) return false

        val motionEvent = MotionEvent.obtain(event)
        val currentY = event.y.toInt()

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                nestedYOffset = 0
                lastMotionY = currentY
                startNestedScroll(View.SCROLL_AXIS_VERTICAL)
            }

            MotionEvent.ACTION_MOVE -> {
                var deltaY = lastMotionY - currentY

                if (dispatchNestedPreScroll(0, deltaY, scrollConsumed, scrollOffset)) {
                    deltaY -= scrollConsumed[1]
                    motionEvent.offsetLocation(0f, scrollOffset[1].toFloat())
                    nestedYOffset += scrollOffset[1]
                }

                lastMotionY = currentY - scrollOffset[1]

                val oldY = scrollY
                val newScrollY = Math.max(0, oldY + deltaY)
                val dyConsumed = newScrollY - oldY
                val dyUnconsumed = deltaY - dyConsumed

                if (dispatchNestedScroll(0, dyConsumed, 0, dyUnconsumed, scrollOffset)) {
                    lastMotionY -= scrollOffset[1]
                    motionEvent.offsetLocation(0f, scrollOffset[1].toFloat())
                    nestedYOffset += scrollOffset[1]
                }

                motionEvent.recycle()
            }

            MotionEvent.ACTION_POINTER_DOWN,
            MotionEvent.ACTION_UP,
            MotionEvent.ACTION_CANCEL -> stopNestedScroll()

            else -> { }
        }

        return super.onTouchEvent(event)
    }

    override fun startNestedScroll(axes: Int, type: Int) = childHelper.startNestedScroll(axes, type)

    override fun stopNestedScroll(type: Int) = childHelper.stopNestedScroll(type)

    override fun hasNestedScrollingParent(type: Int) = childHelper.hasNestedScrollingParent(type)

    override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?, type: Int) =
            childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, type)

    override fun dispatchNestedScroll(dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?, type: Int) =
            childHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow, type)

}

and in the layout leave only WebView:

<com.widget.NestedScrollWebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
Sign up to request clarification or add additional context in comments.

Comments

6

It works for me, add This line to NestedScrollview in XML File.

 android:fillViewport="true"

then set webview height wrap_content.

<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

1 Comment

That works! I upvoted because that's what I experimented just 30 seconds before reading this, and Android Studio was installing right when I was reading this. Funny! Nice find! Catch is to use android:layout_height="wrap_content" with the Webview.
0

I had a similar problem and solved it with setFillViewport (true) A piece of my code

 NestedScrollView scrollView = (NestedScrollView) findViewById (R.id.nest_scrollview);
    scrollView.setFillViewport (true);

And inside the fragment I had a listView where I sat android:nestedScrollingEnabled="true" .. Fixed the scrolling issue

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.