Home » Android » android – How to let only specific fragments scroll inside a ViewPager of CoordinatorLayout?

android – How to let only specific fragments scroll inside a ViewPager of CoordinatorLayout?

Posted by: admin May 14, 2020 Leave a comment

Questions:

Background

I have a viewPager, with 3 fragments and tabs for them. Each fragment has an intro phase (of its own) that doesn’t have any scrollable content.

After leaving the intro phase, there is a recyclerView that the user can scroll in.

The problem

I need to use the new design library, so that when scrolling (only via recyclerView), it will hide the actionBar and let the tabs still be shown.

When the user goes to a fragment that doesn’t have a scrollable content yet, the actionBar should re-appear, similar to what “Google Play Newsstand” has. In fact, I would even be happy to have what they have: as soon as you start swiping left/right, re-show the action bar.

Thing is, if I follow the guidelines and samples, I have 2 issues:

  1. The non-scrollable phase for fragments gets truncated at the bottom, as if it can get scrolled.

  2. I can’t find how to re-show the actionBar, and make it stuck there till I switch to a scrollable content (either by switching to another fragment, or when the content of the current fragment changes to a scrollable content).

What I’ve tried

Here’s a short snippet of the current layout XML file of the activity:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/activity_main__coordinator"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/activity_main__appBarLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:theme="?attr/actionBarTheme">

            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:layoutDirection="ltr"
                android:theme="?attr/actionBarTheme"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                tools:ignore="UnusedAttribute"/>

            <android.support.design.widget.TabLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                app:tabGravity="fill"
                app:tabIndicatorColor="#FFffffff"
                app:tabIndicatorHeight="3dp"/>
        </android.support.design.widget.AppBarLayout>

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

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

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

    <include
        layout="@layout/sliding_menu"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"/>

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

The fragments have a layout of a ViewAnimator that just switches between phases, while one of them is the non-scrollable content, and the other is the RecyclerView.

I’ve tried to add a NestedScrollView/ScrollView the non-scrollable content , and force it to fill itself, using android:fillViewport=”true” , but it didn’t work. For ScrollView it didn’t even allow to scroll.

EDIT: Another thing I’ve tried is to use addOnPageChangeListener on the viewPager, so that in onPageSelected I could set the flags for the toolbar :

AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams();
params.setScrollFlags(!needScrolling? 0 : LayoutParams.SCROLL_FLAG_SNAP | LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | LayoutParams.SCROLL_FLAG_SCROLL);

It works, but it has a issues too:

  1. while scrolling horizontally, I can see the content of the non-scrollable fragment being truncated, and when going to the new fragment (stop touching the screen, to let it snap to the fragment), only then it shrinks its size to fit the correct space.
  2. The toolbar doesn’t get re-shown.
  3. If the toolbar is hidden due to scrolling on another fragment, and I’m now on the non-scrollable fragment, it actually gets less space to fill than it’s supposed to, so it has empty space at the bottom.

EDIT: one solution is to add an empty view of the same height of actionbar (layout_height=”?actionBarSize”) at the bottom of the non-scrollable fragments’s content. However, when the action bar is hidden, I can see the view, so there is empty space. I still need to know how to re-show the actionbar on this case.

The question

How do I set a different behavior for the toolbar, so that it will re-show and stuck on certain states, yet be scrollable only when there is a RecyclerView shown on the current fragment?

How to&Answers: