backslashV
backslashV

Reputation: 51

Rotating icon within FAB not the FAB itself

I am trying to implement a FAB similar to Google Calendar's (Animation here). There the plus icon morphs into the calendar icon and rotates. I can't quite figure out how they are doing this. All I could do it to create two FABs with one being invisible. Once the plus FAB is clicked, I switch the FABs' visibility and perform a rotation. However, this rotation rotates the whole button as opposed to the icon only. Since FABs are square in MD3, this is not very sightly.

My attempt so far:

XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    tools:context=".MainActivity">


    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab_task"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginBottom="24dp"
        android:visibility="invisible"
        app:backgroundTint="@color/fab_calendar"
        app:fabSize="mini"
        app:layout_constraintBottom_toTopOf="@+id/fab_plus"
        app:layout_constraintEnd_toEndOf="@+id/fab_plus"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="@+id/fab_plus"
        app:srcCompat="@drawable/ic_baseline_task_alt_24"
        app:tint="@color/white" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab_plus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"
        android:onClick="plusFabClickListener"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:tint="@color/black"
        app:srcCompat="@drawable/ic_baseline_add_24" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab_calendar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"
        android:onClick="calendarFabClickListener"
        android:rotation="180"
        android:visibility="invisible"
        app:backgroundTint="@color/fab_calendar"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:srcCompat="@drawable/ic_baseline_event_24" />

</androidx.constraintlayout.widget.ConstraintLayout>

JAVA:

public void plusFabClickListener(View view) {
    mFabCalendar.setVisibility(View.VISIBLE);
    ObjectAnimator.ofFloat(mFabCalendar, "rotation", 180f, 360f).setDuration(300).start();
    mFabPlus.setVisibility(View.INVISIBLE);
    toggleMiniFabsVisibility(true);
}

public void calendarFabClickListener(View view) {
    mFabPlus.setVisibility(View.VISIBLE);
    ObjectAnimator.ofFloat(mFabPlus, "rotation", 180f, 0f).setDuration(300).start();
    mFabCalendar.setVisibility(View.INVISIBLE);
    toggleMiniFabsVisibility(false);
}

private void toggleMiniFabsVisibility(boolean show) {
    mFabTask.setVisibility(show ? View.VISIBLE : View.INVISIBLE);;
}

Upvotes: 1

Views: 80

Answers (1)

backslashV
backslashV

Reputation: 51

I managed to achieve this using the website ShapeShifter to animate the icon transitions and put the vector drawable inside my project. You can use the vector drawable just like any other drawable. At the time you set it as the icon for your view, you just need to call animate() on it so it plays the animation. I think Google Calendar is also doing the same. If anyone has a better solution, feel free to comment.

Upvotes: 1

Related Questions