Custom CoordinatorLayout Behavior – Android Kotlin Tutorial

Learn how to create a custom CoordinatorLayout Behavior for views in your Android app!

In this tutorial we will create a ShrinkBehavior which will shrink a FAB whenever there’s a Snackbar displayed. With approach given in this tutorial, you will be able to create any behavior you wish, whether it is rotating the FAB or doing something completely special.

Also, behaviors don’t need to be applied only to floating action buttons. Any subclass of View can have a behavior as long as it is a child of CoordinatorLayout.

 

This post contains all the code that’s been written in this YouTube video.

 

You can also check out this GitHub repository: https://github.com/ResoCoder/BehaviorAndroidTutorial

 

ShrinkBehavior.kt

package com.resocoder.behaviortut

import android.content.Context
import android.support.design.widget.CoordinatorLayout
import android.support.design.widget.Snackbar
import android.util.AttributeSet
import android.view.View


class ShrinkBehavior(context: Context, attributeSet: AttributeSet)
    : CoordinatorLayout.Behavior<View>(context, attributeSet){

    override fun layoutDependsOn(parent: CoordinatorLayout?, child: View?, dependency: View?): Boolean {
        return dependency is Snackbar.SnackbarLayout
    }

    override fun onDependentViewChanged(parent: CoordinatorLayout?, child: View?, dependency: View?): Boolean {
        if (parent == null || child == null || dependency == null)
            return false

        val distanceY = getViewOffsetForSnackbar(parent, child)
        val fractionComplete = distanceY / dependency.height
        val scaleFactor = 1 - fractionComplete

        child.scaleX = scaleFactor
        child.scaleY = scaleFactor
        return true
    }

    private fun getViewOffsetForSnackbar(parent: CoordinatorLayout, view: View): Float{
        var maxOffset = 0f
        val dependencies = parent.getDependencies(view)

        dependencies.forEach { dependency ->
            if (dependency is Snackbar.SnackbarLayout && parent.doViewsOverlap(view, dependency)){
                maxOffset = Math.max(maxOffset, (dependency.translationY - dependency.height) * -1)
            }
        }

        return maxOffset
    }
}

 

FAB Code

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email"
        app:layout_behavior="com.resocoder.behaviortut.ShrinkBehavior"/>

 

About the author 

Matt Rešetár

Matt is an app developer with a knack for teaching others. Working as a Flutter Developer at LeanCode and a developer educator, he is set on helping other people succeed in their Flutter app development career.

You may also like

Flutter UI Testing with Patrol

Flutter UI Testing with Patrol
  • Thank you for your sharing. I am worried that I lack creative ideas. It is your article that makes me full of hope. Thank you. But, I have a question, can you help me?

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
    >