Set starting height of CollapsingToolbarLayout

Stranger B. picture Stranger B. · Oct 10, 2015 · Viewed 20.1k times · Source

I want to be able to scroll on the ImageView inside the CollapsingToolbarLayout. So how that would be possible, and How to set a starting height of that Image view?

My ImageView height is 280p, at the start of the activity I want to show 200p and then I can scroll down to see the rest of the Image. I have seen something similar in WhatsApp application.

Here is a link to see what I want :

enter image description here

My code :

<?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"
    tools:context="com.example.yasser.version6.Profile">

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

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

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@drawable/tof" />

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

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

<include
    android:id="@+id/content"
    layout="@layout/content_profile" />


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

Content profile code :

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    tools:showIn="@layout/activity_profile"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.yasser.version6.Profile">

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

Answer

DmitryArc picture DmitryArc · Oct 15, 2015

Actually AppBarLayout has special method to apply such offset:

final int setAppBarTopBottomOffset(CoordinatorLayout coordinatorLayout, AppBarLayout appBarLayout, int newOffset, int minOffset, int maxOffset)

Unfortunately it has package-private access level, but we can invoke it through such intermediate chain:

private void setAppBarOffset(int offsetPx){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
    AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
    behavior.onNestedPreScroll(mCoordinatorLayour, mAppBarLayout, null, 0, offsetPx, new int[]{0, 0});
}

One thing to be mentioned - this method should be called after mAppBarLayout is already prepared and measured. So the right way is to call it via view's post method.

mCoordinatorLayour = (CoordinatorLayout) findViewById(R.id.root_coordinator);
mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar_layout);

mAppBarLayout.post(new Runnable() {
    @Override
    public void run() {
        int heightPx = findViewById(R.id.iv_header).getHeight();
        setAppBarOffset(heightPx/2);
    }
});