ViewPager in a NestedScrollView
Asked Answered
B

21

124

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>
Baptize answered 1/6, 2015 at 18:48 Comment(8)
Have you tried wrapping your ViewPager inside a LinearLayout ? Just curious if that would render the ViewPager properly.Banjermasin
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 hierarchyBaptize
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?Banjermasin
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 ?Baptize
I pasted a simple example layout here: 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.Banjermasin
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 ?Baptize
Let us continue this discussion in chat.Baptize
@Baptize 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.Contrarily
A
134

I had the same problem. I solved it with the help of setFillViewport (true) if you want to change the xml.

<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"/>

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

If you have an Activity and change it programmatically, then it should be as follows.

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

enter image description here

Alden answered 28/10, 2015 at 7:28 Comment(5)
Note that this can be set in XML as well, just add android:fillViewport="true" to the NestedScrollView object. The documentation describes this attribute as Defines whether the scrollview should stretch its content to fill the viewport..Dragonhead
This does not solve the scrolling problem in placeholder fragmentsTorture
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 issueReasonless
@Krøllebølle NestedScrollView does not have this attribute, you have to set it programmatically.Aquiver
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.Authorize
C
74

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

Cymar answered 22/7, 2015 at 11:26 Comment(13)
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.Meditation
@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.Cymar
i know, i have gone through docs and start this issue as well on google.Meditation
Might better to use a recyclerViewPantaloon
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.Mortgage
@Mortgage thanks for sharing that. I'll try this as soon as I'll get free from my current work and will update the answer. :)Cymar
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 ThanksEviscerate
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?Fonsie
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 searchHoo
can we put view pager even in image view place ?Hiatus
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!Planer
@Cymar i have a nested scroll view with both viewpager and buttons. viewpager is been scrolled but i can't scroll to the buttons #39880970Kanaka
You would have summarized what you did, some of us dont have time to start navigating through your codeObedient
F
52

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

Fbi answered 11/4, 2017 at 10:18 Comment(1)
it solves the problem but the viewpager height will be the match parent (it take whole page height).Mair
Y
31

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

Yellows answered 7/6, 2016 at 8:21 Comment(3)
This is the one that did it for me. Thanks!Cicada
Hey Ino, this seems to be working but when I add one more view on top of the TabLayout, its breaking. Could you give some assistance?Salicin
You have saved my days. :)Gravitation
S
21

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>

Stanislaus answered 21/7, 2015 at 16:7 Comment(4)
Does it work if the content was a coordinator layout with another NestedScrollView? And does the parent CoordinatorLayout listen to the scroll events there?Torture
This work for me. I add the NestedScrollView to every item of my ViewPager instead of the ViewPager. Thanks.Affluence
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.Contagious
Nested scrollview is horrible for recyclerview performance.Memorialize
C
17

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>
Callosity answered 4/6, 2015 at 9:15 Comment(3)
Did you try to encapsulate it into a "android.support.design.widget.CoordinatorLayout" and a collapsing toolbar ?Baptize
You solutions seems to prove the problem is in the height. Found any improvements yet @Callosity ?Rumple
This one worked for me, but i also had to call setFillViewport(true) on the nestedview.Dagney
S
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.

Screeching answered 20/9, 2015 at 10:43 Comment(2)
even if the content was a coordinator layout with another NestedScrollView?Torture
Fragment listview data is not being loaded this way!Contagious
C
9

Just put this line in the NestedScrollView

android:fillViewport="true"
Creese answered 25/5, 2019 at 0:12 Comment(2)
Tons of thanks. What to do if I want to scroll by touching CollapsingToolbarLayout directly?Psychochemical
add " app:layout_behavior="@string/appbar_scrolling_view_behavior" " to your NestedScrollViewStanleigh
T
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>
Thanksgiving answered 7/3, 2016 at 15:53 Comment(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)Dactylic
finally something that works without adding an extra scrolling container! Btw you can set this setNestedScrollingEnabled(true) in xml too: android:nestedScrollingEnabled="true"Unisexual
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 :(Overscrupulous
M
6

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!

Monochasium answered 24/2, 2017 at 17:56 Comment(2)
but the scroll view automatically scrolls to top ? how to fix this ?Numerous
Thank you. you saved me.Memorize
H
4

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.

Hindu answered 22/2, 2016 at 5:42 Comment(0)
R
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();
        }
    }
}
Rutaceous answered 16/8, 2017 at 12:18 Comment(0)
E
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.

Eviscerate answered 23/10, 2015 at 20:18 Comment(0)
E
3

Just add android:fillViewport="true" to NeastedScrollView xml tag

<androidx.core.widget.NestedScrollView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:fillViewport="true"
       app:layout_behavior="@string/appbar_scrolling_view_behavior"
       >
       <androidx.viewpager.widget.ViewPager
           android:id="@+id/viewpager"
           android:layout_width="match_parent"
           android:layout_height="match_parent"/>
   </androidx.core.widget.NestedScrollView>
Eldrida answered 4/7, 2021 at 13:34 Comment(0)
O
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>
October answered 11/6, 2015 at 6:23 Comment(0)
G
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.

Glad answered 17/6, 2015 at 21:2 Comment(2)
So essentially you wrote your own ViewPager implementation? Would you be able to share code on this?Plovdiv
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.Yell
C
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();
Casia answered 15/10, 2015 at 18:10 Comment(1)
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).Eviscerate
W
0

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

yourGridView.setNestedScrollingEnabled(true);

Wandie answered 15/5, 2017 at 15:25 Comment(0)
R
0

I tried many ways but not worked. I referred to this and my problem was solved.

Reverberatory answered 11/2, 2022 at 4:33 Comment(0)
E
-1

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>
Epithelioma answered 7/11, 2015 at 2:41 Comment(0)
B
-1

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.

Bakke answered 21/8, 2017 at 21:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.