ViewPager in a NestedScrollView

前端 未结 19 1995
面向向阳花
面向向阳花 2020-11-27 10:08

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

相关标签:
19条回答
  • 2020-11-27 10:31

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

    0 讨论(0)
  • 2020-11-27 10:36

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

    0 讨论(0)
  • 2020-11-27 10:36

    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.

    0 讨论(0)
  • 2020-11-27 10:36

    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 讨论(0)
  • 2020-11-27 10:37

    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.

    0 讨论(0)
  • 2020-11-27 10:44

    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();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题