117

I need to create an interface like Google Newsstand which is a sort of ViewPager (horizontal scroll) over a collapsing header (vertical scroll). One of my requirements is to use the new Design Support Library presented at the Google IO 2015. (http://android-developers.blogspot.ca/2015/05/android-design-support-library.html)

Based on the sample created by Chris Banes (https://github.com/chrisbanes/cheesesquare) I've reach the point that I'm able to do the collapsing behaviour but with a basic LinearLayout (without horizontal scroll).

I tried to replace the LinearLayout by a ViewPager and I got a blank screen. I played with: width, weight and all kind of view groups but.... still a blank screen. It seems that ViewPager and NestedScrollView don't like each other.

I tried a workaround by using an HorizontalScrollView: it works but I loose the benefit of the PagerTitleStrip feature and the focus on a single panel (I can stop the horizontally between 2 panels).

Now I have no more ideas, if anyone can lead me to a solution...

Thanks

Here is my latest layout file :

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/header_height"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <include
                layout="@layout/part_header"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_collapseMode="parallax"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/activity_main_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

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

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/activity_main_nestedscrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.v4.view.ViewPager
            android:id="@+id/activity_main_viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#FFA0"/>


    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
Kyso84
  • 1,645
  • 4
  • 14
  • 18
  • Have you tried wrapping your `ViewPager` inside a `LinearLayout` ? Just curious if that would render the `ViewPager` properly. – CzarMatt Jun 01 '15 at 18:56
  • Yes I tried but still the same result. I did many tests with many components but the ViewPager is never rendered in a the NestedScrollView no matter the hierarchy – Kyso84 Jun 01 '15 at 19:04
  • I just created a test app with a `ViewPager` inside a `NestedScrollView` as the only layouts - seemed to work fine. I was also able to drop into a `DrawerLayout` successfully. Perhaps there is another aspect of your code preventing the functionality you want. Care to share more of your source? – CzarMatt Jun 01 '15 at 19:24
  • Wow, so you're able to swipe left/right and up/down ? I simply use a FragmentPagerAdapter to display fragments in my pager. Can you share your sample code instead ? – Kyso84 Jun 01 '15 at 19:31
  • I pasted a simple example layout here: http://pastebin.com/jXPw6mtf Edit: You can load whatever fragment you want in the `ViewPager`. I'm able to scroll the views up and down, as well as scroll the `ViewPager` left/right. – CzarMatt Jun 01 '15 at 19:39
  • Ok I saw your code thank you for sharing. I have 2 more questions: 1- Are you able to put a CoordinatorLayout as root view ? 2- What kind of content You have in your ViewPager ? fragements ? – Kyso84 Jun 01 '15 at 19:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/79357/discussion-between-kyso84-and-czarmatt). – Kyso84 Jun 01 '15 at 20:03
  • @Kyso84 but it's not working while setting view pager height is in match_parent. it will work only if, view pager height is giving in the specific number of dp. – Muhammed Haris Mar 22 '21 at 06:31

19 Answers19

127

I meet this problem ,i solve it by setFillViewport (true)

<android.support.v4.widget.NestedScrollView
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"
android:layout_width="match_parent"
android:id="@+id/nest_scrollview"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="mio.kon.yyb.nestedscrollviewbug.ScrollingActivity"
tools:showIn="@layout/activity_scrolling">


    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

in activity

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

enter image description here

mio4kon
  • 1,443
  • 1
  • 9
  • 14
  • 32
    Note that this can be set in XML as well, just add `android:fillViewport="true"` to the `NestedScrollView` object. The [documentation](http://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html) describes this attribute as `Defines whether the scrollview should stretch its content to fill the viewport.`. – Krøllebølle Dec 06 '15 at 20:26
  • 8
    This does not solve the scrolling problem in placeholder fragments – Atieh Jan 22 '16 at 02:07
  • 3
    Thanks! I have sat `android:fillViewport="true"` on `NestedScrollView` and inside the `fragment` I have a `listView` where I sat `android:nestedScrollingEnabled="true"` .. Fixed the scrolling issue – radubogdan Apr 19 '16 at 07:57
  • @Krøllebølle NestedScrollView does not have this attribute, you have to set it programmatically. –  Aug 17 '16 at 13:12
  • Yeah this works for me. I've a problem when I set viewpager's height to match_parent inside NestedScrollView it was not showing the views. – Waheed Nazir Oct 04 '19 at 09:20
71

Okay, I made a small demo with the ViewPager and NestedScrollView. The problem I faced was with the height of ViewPager and the ListView. So I did a little modification on ListView and ViewPager's height measuring.

If anyone would like to look into the code, Here is the link: https://github.com/TheLittleNaruto/SupportDesignExample/

Output:

enter image description here

TheLittleNaruto
  • 7,996
  • 4
  • 47
  • 66
  • not working, if the fragment don;t have listview, even forlistview its working if the number of count of items is same for all fragments. – Pankaj Arora Aug 04 '15 at 07:28
  • @Dev The issue is with the height of View Pager, So, whatever height It'll take in first fragment, then its height will be same for other fragments as well. In that case, you'll have to figure out a way to set the height of the ViewPager dynamically considering set of items for each fragment. – TheLittleNaruto Aug 04 '15 at 07:36
  • i know, i have gone through docs and start this issue as well on google. – Pankaj Arora Aug 04 '15 at 07:40
  • Might better to use a recyclerView – CaptRisky Sep 01 '15 at 10:44
  • 3
    I may be a *little* late to the party but, I was working on this today, and I've got it (mostly) working with adding app:layout_behavior="@string/appbar_scrolling_view_behavior" on both the ViewPager **and** on the parent view of each Fragment. – Graeme Sep 18 '15 at 07:56
  • @Graeme thanks for sharing that. I'll try this as soon as I'll get free from my current work and will update the answer. :) – TheLittleNaruto Sep 18 '15 at 08:11
  • 1
    No doubt that this works, but isn't this overcomplicating the issue? I solved this by getting rid of the `NestedScrollView` and using a `LinearLayout` instead. What would be the benefits of having a `NestedScrollView` over a `LinearLayout` if the whole purpose is to scroll the contents within the ViewPager? Please correct me if I'm wrong. :x Thanks – Cramps Oct 23 '15 at 20:29
  • There is a problem with project, if I scroll one page in view pager, other ones scroll as well. Is there any way to achieve that somehow? – Ali Yucel Akgul Jan 31 '16 at 21:38
  • how to diplay list of images in the place og image view from above using viewpager image urls from server,and below list data please help me along with search – Harsha Feb 18 '16 at 07:16
  • can we put view pager even in image view place ? – andro Apr 08 '16 at 11:10
  • 1
    Thank you so much! I was at the point of pulling my hair out, and your WrapContentHeightViewPager works like a charm. I owe you one! – Mavamaarten May 09 '16 at 23:34
  • @TheLittleNaruto i have a nested scroll view with both viewpager and buttons. viewpager is been scrolled but i can't scroll to the buttons http://stackoverflow.com/questions/39880470/relative-layout-inside-nestedscrollview-is-not-been-scrolled – Edijae Crusar Oct 05 '16 at 17:47
  • You would have summarized what you did, some of us dont have time to start navigating through your code – Declan Nnadozie Apr 03 '20 at 15:17
47

Add android:fillViewport="true" in your NestedScrollView . period.

Sujit Yadav
  • 2,367
  • 1
  • 12
  • 16
30

Instead of placing ViewPager inside the NestedScrollView, do it the other way around.

Place the NestedScrollView in the child Views inside the ViewPager which in essence is the Fragment's layout. It's also very likely that you won't even need to use NestedScrollView if your Fragment's list layout is very simple.

Example Layouts

Activity's Layout:

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="@dimen/app_bar_height"
                android:scaleType="centerCrop"
                android:src="@drawable/my_bg"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.8"
                app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

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

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.design.widget.TabLayout
            android:id="@+id/content_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>

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

If you don't need the TabLayout, you can ditch the LinearLayout and make ViewPager standalone. But be sure to use app:layout_behavior="@string/appbar_scrolling_view_behavior" in ViewPager attributes.

Simple Fragment's Layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Complex Fragment's Layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hello World"/>
    </RelativeLayout>
</android.support.v4.widget.NestedScrollView>

Example App: CollapsingToolbarPoc

enter image description here

Ino
  • 451
  • 4
  • 5
20

Had the same issues.

When putting the NestedScrollView around the ViewPager, it wouldn't work.

What DID work though is putting the NestedScrollView inside the layout of the fragment I'm loading inside the ViewPager.



<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@id/fragment_detail"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="fill_vertical"
            android:orientation="vertical">
    ...Content...
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

ThemBones
  • 337
  • 1
  • 11
  • Does it work if the content was a coordinator layout with another NestedScrollView? And does the parent CoordinatorLayout listen to the scroll events there? – Atieh Jan 15 '16 at 19:02
  • This work for me. I add the NestedScrollView to every item of my ViewPager instead of the ViewPager. Thanks. – jerogaren Mar 15 '16 at 12:51
  • I have swipefreshlayout in fragment, according to ur solution, I put NestedScrollview in fragment, above swipeRefreshLayout.. then data is not being loaded. It didnt work. – Palak Darji Apr 10 '16 at 05:00
16

you can try like this, viewpager works fine, but the viewpager's height is fixed.

i am still finding the better solution ..., so please let me know any point can do it better, thanks

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="800dp"
        android:orientation="vertical">

        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>
Paul
  • 161
  • 1
  • 5
  • Did you try to encapsulate it into a "android.support.design.widget.CoordinatorLayout" and a collapsing toolbar ? – Kyso84 Jun 05 '15 at 12:48
  • You solutions seems to prove the problem is in the height. Found any improvements yet @Paul ? – jasxir Jun 24 '15 at 07:14
  • 3
    This one worked for me, but i also had to call setFillViewport(true) on the nestedview. – Akah Feb 20 '16 at 15:01
13

I had the same issue, and just fixed it with some changes. ViewPager doesn't work within the NestedScrollView. Simply put your ViewPager as a direct child of your CoordinatorLayout. Then the content for each ViewPager's Fragment should be enclosed in NestedScrollView. That's it.

BST Kaal
  • 2,743
  • 5
  • 31
  • 51
7

just put this line in NestedScrollView

android:fillViewport="true"
gholam
  • 120
  • 1
  • 5
6

You dont need use the NestedScrollView to have the parallax effects. try something like this:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true">

        <android.support.v7.widget.Toolbar
            android:id="@+id/my_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways"/>

        <android.support.design.widget.TabLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/my_tab_layout"
            android:fillViewport="false"
            app:tabMode="fixed"/>
     </android.support.design.widget.AppBarLayout>

            <android.support.v4.view.ViewPager
                android:id="@+id/my_view_pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

</android.support.design.widget.CoordinatorLayout>
Chintan Rathod
  • 24,674
  • 13
  • 76
  • 92
  • 3
    This will work, as long as all your `ViewPager` fragments are ether `RecyclerView`, or `NestedScrollView`. If they aren't (e.g. `ListView`), then a workaround for Lollipop and above is to call `listView.setNestedScrollingEnabled(true)` – AndyDeveloper Mar 08 '16 at 00:53
  • finally something that works without adding an extra scrolling container! Btw you can set this setNestedScrollingEnabled(true) in xml too: android:nestedScrollingEnabled="true" – Analizer Apr 26 '16 at 09:44
  • 1
    If I run my app, collapse the toolbar whilst in one tab, switch tab, then pull the toolbar back down, it's empty. Have to switch tabs whilst it's in non-collapsed state to get it back again. So close, yet so far :( – me-- May 18 '16 at 03:42
4

I had a layout with an app toolbar with NestedScrollView below it, then inside nested toolbar was a LinearLayout, below the LinearLayout was a view pager. Idea was the LinearLayout inside the NestedScrollView was fixed - you could slide left/right between the views of the view pager but this content wouldn't move, horizontally at least. You should still be able to scroll all the content vertically because of the nested scroll view. That was the idea. So I set nested NestedScrollView height to match_parent, fill viewport, then all the child layouts/ViewPager to wrap_content.

In my head that was right. But it didn't work - ViewPager allowed me to go left/right, but no vertical scrolling, whether the viewpager page content pushed below the bottom of the current screen or not. Turns out it was basically because the ViewPager doesn't respect wrap_content across its various pages.

I got round this by subclassing the ViewPager to make it change height depending on the current selected item, sort of forcing it to behave like layout_height="wrap_content":

public class ContentWrappingViewPager extends ViewPager {

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        if (getChildCount() > getCurrentItem()) {
            View child = getChildAt(getCurrentItem());
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

Solution was inspired by this answer. Worked for me!

Community
  • 1
  • 1
Breeno
  • 2,657
  • 2
  • 26
  • 26
4

Use below customized class to resolve your problem. Don't forget to call onRefresh() method on pagechangelistener.

public class ContentWrappingViewPager extends ViewPager
{
    private int width = 0;
    public ContentWrappingViewPager(Context context) {
        super(context);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int height = 0;
        width = widthMeasureSpec;
        if (getChildCount() > getCurrentItem()) {
            View child = getChildAt(getCurrentItem());
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void onRefresh()
    {
        try {
            int height = 0;
            if (getChildCount() > getCurrentItem()) {
                View child = getChildAt(getCurrentItem());
                child.measure(width, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                int h = child.getMeasuredHeight();
                if(h > height) height = h;
            }

            int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
            ViewGroup.LayoutParams layoutParams = this.getLayoutParams();
            layoutParams.height = heightMeasureSpec;
            this.setLayoutParams(layoutParams);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Kuldeep Sakhiya
  • 2,956
  • 1
  • 14
  • 16
3

I was having a similar problem (but without CollapsingToolbarLayout, just a simple Toolbar + TabLayout within the AppBarLayout). I wanted the Toolbar to scroll out of sight when scrolling down the contents of a ViewPager within the NestedScrollView.

My layout went something like this:

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true">

            <android.support.v7.widget.Toolbar
                android:id="@+id/my_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"/>

            <android.support.design.widget.TabLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/my_tab_layout"
                android:fillViewport="false"
                app:tabMode="fixed"/>
         </android.support.design.widget.AppBarLayout>

         <android.support.v4.widget.NestedScrollView
                android:id="@+id/container"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fillViewport="true"
                android:layout_gravity="fill_vertical"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.v4.view.ViewPager
                    android:id="@+id/my_view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                     app:layout_behavior="@string/appbar_scrolling_view_behavior">
                </android.support.v4.view.ViewPager>
         </android.support.v4.widget.NestedScrollView>

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

This layout wasn't working as intended, but I solved it by simply getting rid of the NestedScrollView and using a LinearLayout instead. It worked for me right away on Android Support Library v23.1.0. Here's how the layout ended up:

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true">

            <android.support.v7.widget.Toolbar
                android:id="@+id/my_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"/>

            <android.support.design.widget.TabLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/my_tab_layout"
                android:fillViewport="false"
                app:tabMode="fixed"/>
         </android.support.design.widget.AppBarLayout>

         <LinearLayout
            android:orientation="vertical"
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="4dp"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.v4.view.ViewPager
                    android:id="@+id/my_view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                     app:layout_behavior="@string/appbar_scrolling_view_behavior">
                </android.support.v4.view.ViewPager>
         </LinearLayout>

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

PS: These were actually two layout files in my project. I copied and pasted them here and tried to structure them as it would look like in a single file. I'm sorry if I screwed up while copy-pasting but please let me know if that's the case so I can fix it.

Cramps
  • 444
  • 5
  • 15
3

I removed NestedScrollView from the main layout and inserted as a Parent in all my Fragment layouts that were supposed to load in ViewPager fixed this issue for me.

Riddhish Ojha
  • 145
  • 2
  • 13
1

The following should ensure the proper height of the view pager. The fragment is the first fragment provided by the view pager.

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <fragment
            class="com.mydomain.MyViewPagerFragment"
            android:id="@+id/myFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"/>

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>
Jon
  • 517
  • 5
  • 9
1

I have the same wish, nest a ViewPager inside a NestedScrollView. But it doesn't work for me neither. In my case, the ViewPager is inside a Fragment so I can switch content depending on the interactions with the drawer. Of course, AppBar, collapse, etc and all new feature of support library must work.

If a user vertically scrolls a page in the pager, I want other pages to be scrolled the same, to give the user the overall impression that the pager itself scrolled.

What I did, which works, is that I no longer embed the ViewPager inside a NestedScrollView, instead, I embed the content of the contained fragments inside a NestedScrollView.

Then, in case of a scroll in one fragment, I inform the container of the new scrolling position, which stores it.

Finally, on a swipe left or right detected from the pager (using addOnPageChangeListener looking for drag states) I inform the target left or right fragment where it must scroll (based on the container knowledge of it) to be aligned from the fragment I come from.

  • So essentially you wrote your own ViewPager implementation? Would you be able to share code on this? – joseph Jun 22 '15 at 16:41
  • I did something similar to this (if I understand it correctly), which is to do a linear layout in your coordinator layout, which contains the tablayout (if needed) and the viewpager, instead of a nested scrollview. The fragments themselves then have the nested scrollview as their root element. This works for me, but I would prefer just having one nestedscrollview instead of repeating it in each fragment. – Chris Jul 16 '15 at 20:46
0

I know one working solution: You use Activity, with CoordinatorLayout and use FrameLayout, container. Then. use fragment manager to put fragment in container. For example my code:

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

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:elevation="0dp">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        app:layout_scrollFlags="scroll|enterAlways"
        android:layout_height="@dimen/toolbar_height"
        android:background="?attr/colorPrimary"
        android:gravity="center">

    </android.support.v7.widget.Toolbar>


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

<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

</FrameLayout>

And Fragment:

<LinearLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.improvemdia.inmyroom.MainFragment">

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Then use FragmentManager

getSupportFragmentManager().beginTransaction()
            .replace(R.id.container, new MainFragment())
            .commit();
Aleksandr Gorshkov
  • 453
  • 1
  • 6
  • 15
  • I think the `LinearLayout` within the Fragment's layout is unnecessary here. See my answer, I used a `LinearLayout` instead of a `FrameLayout` in my Activity's layout, and my fragment's root is a ViewPager (no wrapping layout). – Cramps Oct 23 '15 at 20:24
0

After spending hours tried all of the suggestions above, finally I made it work. The key is putting NestedScrollView inside PageViewer, AND set layout_behavior to '@string/appbar_scrolling_view_behavior' for BOTH views. The final layout is like

<CoordinatorLayout>
    <ViewPager app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <NestedScrollView fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <Content>...</Content>
        </NestedScrollView>
    </ViewPager>
    <AppBarLayout>...</AppBarLayout>
</CoordinatorLayout>
0

you just removed the NestedScrollView on your xml and add this code on your class

yourGridView.setNestedScrollingEnabled(true);

0

Actually the NestedScrollView doesn't need to to be direct sibling of CollapsingToolbarLayout in CoordinatorLayout. I have achieved something realy bizzare. The appbar_scrolling_view_behavior works in 2 nested fragments.

My activity layout:

<android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.AppBarLayout>

            <android.support.design.widget.CollapsingToolbarLayout>

                <include
                    layout="@layout/toolbar"/>

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

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

    <FrameLayout
        android:id="@+id/container"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

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

In the "container" frameLayout I have inflated this fragment:

<android.support.constraint.ConstraintLayout>

    ... some content ...

    <android.support.v4.view.ViewPager/>

    ...

</android.support.constraint.ConstraintLayout>

And fragments inside that ViewPager looks like this:

<RelativeLayout>

    <android.support.v7.widget.RecyclerView/>

    ....

</RelativeLayout>

Fact that NestedScrollView can be so deep in the CoordinatorLayout children hierarchy and scroll behaviors stil works did suprised me.

Alex Mensak
  • 150
  • 1
  • 2
  • 14