How to implement Floating Action Button with Animation in Android (without plugin)
How to implement Floating Action Button with Animation in Android (without plugin).
In this tutorial, we are going to create the floating action button with animations without any plugins or third-party libraries. We are going to create drawable animation files for our animations.
and
Feel free to visit my previous tutorial
Extended Floating Action Button
Floating Action Button with BottomAppBar
Before going to create it let’s see what we’re going to see.
Now, let’s create the floating action button with animations.
Step 1: create the animations files
go to the res folder and create a new Android Resource Directory named “menu” (/res/New/Android Resource Directory/menu). And in the menu resource directory create new animation drawable files. Here I used four animation drawable files.
1. fab_open.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"> <scale
android:fromXScale="0.0"
android:fromYScale="0.0"
android:toXScale="0.8"
android:toYScale="0.8"
android:pivotX="50%"
android:pivotY="50%"
android:duration="300"
android:interpolator="@android:anim/linear_interpolator"/> <alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="300"
android:interpolator="@android:anim/accelerate_interpolator"/></set>
2. fab_close.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"> <scale
android:fromXScale="0.8"
android:fromYScale="0.8"
android:toXScale="0.0"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="300"
android:interpolator="@android:anim/linear_interpolator"/> <alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="300"
android:interpolator="@android:anim/accelerate_interpolator"/></set>
3. rotate_forward.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"> <rotate android:fromDegrees="0"
android:toDegrees="45"
android:pivotX="50%"
android:pivotY="50%"
android:duration="300"
android:interpolator="@android:anim/linear_interpolator"/></set>
4. rotate_backward.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"> <rotate android:fromDegrees="45"
android:toDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="300"
android:interpolator="@android:anim/linear_interpolator"/></set>
Step 2: now design the main XML file
now in the main XML file, create some floating action buttons. Here the visible FAB acts as parent FAB and the invisible FAB acts as child FAB.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
tools:context=".AnimateFABActivity"> <com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_add"/> <com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab1"
android:layout_gravity="bottom|end"
android:layout_marginEnd="90dp"
android:layout_marginBottom="16dp"
android:src="@drawable/ic_camera"
android:visibility="invisible"/> <com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fab2"
android:layout_gravity="bottom|end"
android:layout_marginBottom="90dp"
android:layout_marginEnd="16dp"
android:src="@drawable/ic_folder"
android:visibility="invisible"/></androidx.coordinatorlayout.widget.CoordinatorLayout>
here the first FAB acts as parent FAB. When we click on that FAB, other FABs will popup with some animation effects. Let’s add functionalities for these buttons with animation effects.
Step 3: add functionality
now in the main java file, register your FABs and Animations. Then create a function for animation so that we can handle the animations with the button clicks.
public class AnimateFABActivity extends AppCompatActivity { FloatingActionButton fab, fab1, fab2;
Animation fabOpen, fabClose, rotateForward, rotateBackward;
boolean isOpen = false; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animate_f_a_b); fab = (FloatingActionButton) findViewById(R.id.fab);
fab1 = (FloatingActionButton) findViewById(R.id.fab1);
fab2 = (FloatingActionButton) findViewById(R.id.fab2); fabOpen = AnimationUtils.loadAnimation
(this,R.anim.fab_open);
fabClose = AnimationUtils.loadAnimation
(this,R.anim.fab_close);
rotateForward = AnimationUtils.loadAnimation
(this,R.anim.rotate_forwawrd);
rotateBackward = AnimationUtils.loadAnimation
(this,R.anim.rotate_backward); fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
animateFab();
}
});
fab1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
animateFab();
Toast.makeText(AnimateFABActivity.this,
"camera click", Toast.LENGTH_SHORT).show();
}
});
fab2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
animateFab();
Toast.makeText(AnimateFABActivity.this,
"folder click", Toast.LENGTH_SHORT).show();
}
});
} private void animateFab(){
if (isOpen){
fab.startAnimation(rotateForward);
fab1.startAnimation(fabClose);
fab2.startAnimation(fabClose);
fab1.setClickable(false);
fab2.setClickable(false);
isOpen=false;
}else {
fab.startAnimation(rotateBackward);
fab1.startAnimation(fabOpen);
fab2.startAnimation(fabOpen);
fab1.setClickable(true);
fab2.setClickable(true);
isOpen=true;
}
}
}