ConstraintLayout is similar to RelativeLayout and provides more flexibility than RelativeLayout. Views are placed with a relationship with each other furthermore  Android Studio layout editor provides advanced editing controls. Android application having animations gives a very good user experience. Creating animations in Android is simple but still takes lots of efforts for complex animations. With ConstraintLayout we can create complex animations with fewer efforts. This tutorial will a demonstration of Keyframe Animations with ConstraintLayout and ConstraintSet.

DOWNLOAD SOURCE CODE OR APK

DEMO

Keyframe Animations with ConstraintLayout and ConstraintSet | loopwiki.com

Keyframe Animations with ConstraintLayout and ConstraintSet Example.

Keyframe Animations with ConstraintLayout and ConstraintSet | Output

Adding ConstraintLayout Library to your project

STEP 1: Create or open an existing Android Studio project. Open build.gradle of project module and add the following lines to it.

repositories {
    maven {
        url 'https://maven.google.com'
    }
}

STEP 2: Open app level build.gradle modify it and add a dependency for ConstraintLayout as given below.

dependencies {
   
    /*Add constraint layout dependency*/
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
  
    /*Add cardview dependency for designing layout with cards*/ 
    implementation 'com.android.support:cardview-v7:27.0.2'
}

STEP 3: Download this images and add it to res -> drawable folder 

STEP 4: Create new layout inside res -> layout -> key_frame_default.xml. This layout is the first frame of animation. Bind all the data and positioning information in this view as shown below.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/constrainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center">

    <android.support.v7.widget.CardView
        android:id="@+id/carViewOne"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/carViewTwo"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/imageViewOne"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_above="@+id/textViewOne"
                android:scaleType="centerCrop"
                android:src="@drawable/fruit_one" />

            <TextView
                android:id="@+id/textViewOne"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:gravity="center"
                android:text="Card One"
                android:textAppearance="@style/TextAppearance.AppCompat.Large" />
        </RelativeLayout>

    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:id="@+id/carViewTwo"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/carViewOne"
        app:layout_constraintTop_toTopOf="parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:src="@drawable/fruit_two"
                android:scaleType="centerCrop"
                android:id="@+id/imageViewTwo"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_above="@+id/textViewTwo" />

            <TextView
                android:id="@+id/textViewTwo"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:gravity="center"
                android:text="Card Two"
                android:textAppearance="@style/TextAppearance.AppCompat.Large" />
        </RelativeLayout>

    </android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>

STEP 5: Now create new layout res -> layout -> key_frame_one.xml. This layout will contain only positioning information.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_gravity="center">

    <android.support.v7.widget.CardView
        android:id="@+id/carViewOne"
        android:layout_width="180dp"
        android:layout_height="200dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/imageViewOne"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_above="@+id/textViewOne" />

            <TextView
                android:id="@+id/textViewOne"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:gravity="center"
                android:text="Card One"
                android:textAppearance="@style/TextAppearance.AppCompat.Large" />
        </RelativeLayout>

    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:id="@+id/carViewTwo"
        android:layout_width="180dp"
        android:layout_height="200dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/carViewOne">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/imageViewTwo"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_above="@+id/textViewTwo" />

            <TextView
                android:id="@+id/textViewTwo"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:gravity="center"
                android:text="Card Two"
                android:textAppearance="@style/TextAppearance.AppCompat.Large" />
        </RelativeLayout>

    </android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>

STEP 6: Now we will create a new activity. So create new layout res -> layout -> content_main.xml. Add the following lines to it. The layout will contain two buttons at the bottom. defaultKeyFrameButton is for moving layout to the default position. KeyFrameOneButton will move default layouts child’s positions to as defined in key_frame_one.xml layout with animation.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <!--include default key frame in activity layout-->
    <include layout="@layout/key_frame_default" />


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:weightSum="2">

        <Button
            android:id="@+id/defaultKeyFrameButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Move to Default" />

        <Button
            android:id="@+id/KeyFrameOneButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Move to KeyFrameOne" />
    </LinearLayout>

</RelativeLayout>

STEP 7: Create new layout  res -> layout -> activity_main.xml. add following lines to it.

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

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

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

    <include layout="@layout/content_main" />


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

STEP 8: Create new class package name -> MainActivity.java. Add following code to it.

import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.constraint.ConstraintSet;
import android.support.transition.TransitionManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Bind  constrainLayout
        final ConstraintLayout constrainLayout = findViewById(R.id.constrainLayout);
        //Bind buttons
        Button defaultKeyFrameButton = findViewById(R.id.defaultKeyFrameButton);
        Button KeyFrameOneButton = findViewById(R.id.KeyFrameOneButton);
        defaultKeyFrameButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //defaultKeyFrameButton clicked create new ConstraintSet
                ConstraintSet constraintSet = new ConstraintSet();
                //Clone positioning information from @key_frame_default.xml in ConstraintSet
                constraintSet.clone(MainActivity.this, R.layout.key_frame_default);

                //beginDelayedTransition is Convenience method to animate to a new
                // scene defined by all changes within
                // the given scene root between calling
                // this method and the next rendering frame.
                TransitionManager.beginDelayedTransition(constrainLayout);
                //Then apply ConstraintSet to ConstraintLayout
                //this will move views with animation to positions
                //as defined in key_frame_default.xml layout
                constraintSet.applyTo(constrainLayout);
            }
        });
        KeyFrameOneButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //KeyFrameOneButton clicked create new ConstraintSet
                ConstraintSet constraintSet = new ConstraintSet();
                //Clone positioning information from @key_frame_one.xml in ConstraintSet
                constraintSet.clone(MainActivity.this, R.layout.key_frame_one);
                //beginDelayedTransition is Convenience method to animate to a new
                // scene defined by all changes within
                // the given scene root between calling
                // this method and the next rendering frame.
                TransitionManager.beginDelayedTransition(constrainLayout);
                //Then apply ConstraintSet to ConstraintLayout
                //this will move views with animation to positions
                //as defined in key_frame_one.xml layout
                constraintSet.applyTo(constrainLayout);
            }
        });

    }
}

TransitionManager.beginDelayedTransition():

beginDelayedTransition is a Convenience method to animate to a new scene defined by all changes within the given scene root between calling this method and the next rendering frame.

constraintSet.clone(activity,layout):

This method will clone all the positioning information from the layout and will store in constraints object.

STEP 9: Mention this activity in manifest.xml to as shown below.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.loopwiki.constrinlayoutandroidexample">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

STEP 10: Run the application.

Keyframe Animations with ConstraintLayout and ConstraintSet | Output

If you still have any queries, please post them in the comments section below, I will be happy to help you.

Author

Hello there, My name is Amardeep founder of loopwiki.com. I have experience in many technologies like Android, Java, Php, etc. In this variety of technologies, I love Android App Development. If you have any idea and you want me to develop for you then let's have chat Conatct

Write A Comment