How to implement scrolling pattern for Android

Ramil Gabdrakhmanov
Flatstack Thoughts
Published in
2 min readJun 17, 2016

--

I am sure that everyone has heard of Material Dеsign. In this article I am going to share how to implement scrolling pattern for Android mobile app by using CoordinatorLayout widget. The objective is to create the behaviour demonstrated in the video below:

CoordinatorLayout

As the self-explanatory title suggests, the aim of this widget is to enable coordination of elements. In this example the widget coordinates 4 elements : AppBarLayout, NestedScrollView, Toolbar and CircleImageView.

<LinearLayout…
<android.support.design.widget.CoordinatorLayout...
<android.support.design.widget.AppBarLayout…/>
<android.support.v4.widget.NestedScrollView…/>
<android.support.v7.widget.Toolbar…/>
<de.hdodenhof.circleimageview.CircleImageView…/>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>

CoordinatorLayout.Behavior is an integral part of CoordinatorLayout. This class helps to implement customised behavior of the element, within the CoordinatorLayout container, against the other components. It contains 2 main methods:

  1. layoutDependsOn(CoordinatorLayout parent, CircleImageView child, View dependency)
  2. onDependentViewChanged(CoordinatorLayout parent, CircleImageView child, View dependency)

The first one should return true, if we need to respond to dependency changes. And as for the second method, we should describe the actual response to the changes. There are several built-in implementations: AppBarLayout.Behavior, AppBarLayout.ScrollingViewBehavior, BottomSheetBehavior<V extends View>, FloatingActionButton.Behavior,SwipeDismissBehavior<V extends View>.

As you can see from the video above, the round image containing logo is moving to the corner; its position and size depend on where the Toolbar is placed. The written IconImageBehavior has been extended from CoordinatorLayout.Behavior class. Here are its 2 overridden methods:

...
@Override
public boolean layoutDependsOn(CoordinatorLayout parent,
CircleImageView child, View dependency) {
return dependency instanceof Toolbar;
}

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent,
CircleImageView child, View dependency) {
initProperties(child, dependency);

int maxScrollDistance = (int) (mStartToolbarPosition -
mStatusBarHeight);
float expandedPercentageFactor = dependency.getY() /
maxScrollDistance;

float distanceYToSubtract = ((mStartYPosition - mFinalYPosition)
* (1f - expandedPercentageFactor)) + (child.getHeight() / 2);

float distanceXToSubtract = ((mStartXPosition - mFinalXPosition)
* (1f - expandedPercentageFactor)) + (child.getWidth() / 2);

float heightToSubtract = ((mStartHeight - mFinalHeight) *
(1f - expandedPercentageFactor));

child.setY(mStartYPosition - distanceYToSubtract);
child.setX(mStartXPosition - distanceXToSubtract);

CoordinatorLayout.LayoutParams lp =
(CoordinatorLayout.LayoutParams) child.getLayoutParams();
lp.width = (int) (mStartHeight - heightToSubtract);
lp.height = (int) (mStartHeight - heightToSubtract);
child.setLayoutParams(lp);
return true;
}
...

In order to apply this Behavior it is required to add the following attribute to the icon in the relevant xml file:

app:layout_behavior=”fs.com.coordinatorlayout.IconImageBehavior”

It is all you have to do.

Conclusion:

It is totally awesome that Google not only offers the concepts of interfaces, but also supports them with the handy tools for their native implementation. Moreover, CoordinatorLayout comes together with the support library, which means that this widget can be applied in pre-­lollipop devices.

The source code is stored in this repository together with other useful examples, which might be helpful when implementing the most common tasks.

I hope you will find this article helpful. In case you have any questions or comments, please let me know in the comments section below.

--

--