How to apply fitsSystemWindows on Fragment pages of a ViewPager?

868 Views Asked by At

I can't get my pages of my ViewPager respect the statusbar height. My ViewPager has several pages, on one of them there is an image that needs to go under the translucent statusbar. The rest of the pages only require a coloured statusbar, so my idea was to use fitsSystemWindows="true" on the fragment layouts that will serve as pages for the viewpager. But This doesn't work. It seems on the first draw only the second pages gets the paddings applied. But when scrolling through the pages. It disappears. So it seems to me that the pages don't get the dispatch from the ViewPager to apply the insets. But I have no clue how to make it happen.

I have tried to do something with public static void setOnApplyWindowInsetsListener(View v, OnApplyWindowInsetsListener listener), but I couldn't get working. My idea was to somehow on every new page to apply the insets. Maybe it is the right approach, but I couldn't find the right place to call this method.

So is there anybody that can help me address this problem? I will place some of my code below to give some context on the problem.

Activity.xml

<..WindowInsetsFrameLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

This is a custom layoutmanager to support changing fragments (fragment transitions) and apply the windowInset again. Just for reference this is the code:

public class WindowInsetsFrameLayout extends FrameLayout {
    public WindowInsetsFrameLayout(@NonNull Context context) {
        this(context, null);
    }

    public WindowInsetsFrameLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public WindowInsetsFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        // Look for replaced fragments and apply the insets again.
        setOnHierarchyChangeListener(new OnHierarchyChangeListener() {
            @Override
            public void onChildViewAdded(View parent, View child) {
                requestApplyInsets();
            }

            @Override
            public void onChildViewRemoved(View parent, View child) {

            }
        });
    }
}

Then at some point in time I load the following fragment to the fragment_container.

fragmentWithViewpager.xml

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.ViewPagerController
        android:id="@+id/view_pager_controller"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:showConfirmButton="true" />
</android.support.constraint.ConstraintLayout>

Where the ViewPagerController is a holder for the ViewPager, TabLayout(for the page indication of the ViewPager) and some buttons that I omitted in the layout below.

ViewPagerController

<merge>

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/tab_layout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="spread" />

  ...some other buttons for next en previous of the ViewPager...

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/size_48"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="parent"
        app:layout_constraintStart_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/view_pager"
        app:tabBackground="@drawable/tab_selector"
        app:tabIndicatorHeight="0dp" />
</merge>

And finally the majorty of the pages for the ViewPager have this layout:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="handler"
            type="fragmentX" />
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/background_white">

        <android.support.constraint.ConstraintLayout
            android:id="@+id/top_panel"
            android:layout_width="0dp"
            android:layout_height="@dimen/header_input_height"
            android:background="@color/colorPrimary"
            android:fitsSystemWindows="true"
            android:paddingEnd="@dimen/size_16"
            android:paddingStart="@dimen/size_16"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <ImageButton
                android:id="@+id/close_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="?attr/actionBarItemBackground"
                android:minHeight="@dimen/size_48"
                android:minWidth="@dimen/size_48"
                android:onClick="@{(V) -> handler.onClose()}"
                android:src="@drawable/ic_close"
                app:layout_constraintBottom_toBottomOf="@id/icon_img"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="@id/icon_img" />

            <ImageView
                android:id="@+id/icon_img"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/size_16"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/ic_logo" />

            <TextView
                android:id="@+id/title_txt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/size_32"
                android:fontFamily="@font/alvania_regular"
                android:text="title or page"
                android:textColor="@color/white"
                android:textSize="@dimen/font_size_biggest"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@id/icon_img" />

            <TextView
                android:id="@+id/message_txt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/size_8"
                android:alpha="0.87"
                android:fontFamily="@font/frutiger_light"
                android:gravity="center"
                android:lineSpacingExtra="8sp"
                android:text="sub title fo a page"
                android:textColor="@color/white"
                android:textSize="20sp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@id/title_txt" />

         </android.support.constraint.ConstraintLayout>
     ...more views
     </android.support.constraint.ConstraintLayout>
</layout>
1

There are 1 best solutions below

0
On

First of all you have to apply Fullscreen to your activity so all fragments in your activity will be on fitsSystemWindow (Fullscreen), then on every fragment you can set statusBar color, which will trigger fullscreen or normal case. If statubar transparent then fragment in fullscreen. Enable Fullscreen:

window.decorView.systemUiVisibility =
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
            View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

Enable/Disable Fullscreen by coloring StatusBar:

activity?.window?.statusBarColor = Color.TRANSPARENT //Fullscreen
activity?.window?.statusBarColor = Color.TRANSPARENT //non-Fullscreen

Just enable disable it when your Fullscreen is visible or hidden

Read post about it: https://medium.com/jama9779/single-activity-with-fullscreen-simple-fragments-fefe7f041765