Android CollapsingToolbarLayout with custom View

I had the same problem and spend many hours trying to find a solution. My solution was to add the collapsing Views (ImageView and TextView) inside the CollapsingToolbarLayout and then handle the transition in code. This way it’s more flexible and simpler than extending from CollapsingToolbarLayout.

First you’ll need to add your Views inside the CollapsingToolbarLayout with the parallax properties:

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop:"80dp"
            android:src="https://stackoverflow.com/questions/30886216/@drawable/icon"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.8"/> //set vertical transition here

Then set the scaling of the Views with the help of an OnOffsetchangeListner:

  private static final float SCALE_MINIMUM=0.5f;
  appBarLayout.setOnWorkingOffsetChange(new  ControllableAppBarLayout.OnWorkingOffsetChange() {
        @Override
        public void onOffsetChange(int offSet, float collapseDistance) {
            imageView.setScaleX(1 + (collapseDistance * SCALE_MINIMUM));
            imageView.setScaleY(1 + (collapseDistance * SCALE_MINIMUM));

            textView.setScaleX(1 + (collapseDistance * SCALE_MINIMUM));
            textView.setScaleY(1 + (collapseDistance * SCALE_MINIMUM));

            // You can also setTransitionY/X, setAlpha, setColor etc.
        }
    });

Somehow the default offsetChangedListener didn’t work properly for me (you probably still should try it with the default listener first), so I used the ControllableAppBarLayout from https://gist.github.com/blipinsk/3f8fb37209de6d3eea99 and added the following:

private OnWorkingOffsetChange onWorkingOffsetChange;

@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
    if (!isInEditMode()) {
        onWorkingOffsetChange.onOffsetChange(i, (float) i / appBarLayout.getTotalScrollRange());
    }
}

public void setOnWorkingOffsetChange(OnWorkingOffsetChange listener) {
    this.onWorkingOffsetChange = listener;
}

public interface OnWorkingOffsetChange {
    void onOffsetChange(int offSet, float collapseDistance);
}

The only problem is, that you would need to set
app:contentScrim="#00000000" (transparent)
for your CollapsingToolbarLayout, so your views are still visible when the toolbar is collapsed. If you really need the collapsing-background effect I’m sure you could “fake” this by setting the alpha of a background ImageView in the OffsetChangeListener. 😉

Leave a Comment