How to rotate floating action button without rotating shadow?
Asked Answered
N

6

19

I rotate the FAB in such a simple way:

fab.startAnimation(AnimationUtils.loadAnimation(this, R.anim.rotate));

rotate.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="1000"/>
</set>

This works, but together with the FAB its shadow rotates. But I need only the FAB to rotate (or even its src image, if there's any difference).

Noel answered 22/7, 2015 at 11:52 Comment(1)
My solution with rotating ImageView over FAB #29426638Ase
R
30

Did you try with the animate method provided by the Compat library? I too had the same problem when using Animation utils

final OvershootInterpolator interpolator = new OvershootInterpolator();
ViewCompat.animate(fab).
           rotation(135f).
           withLayer().
           setDuration(300).
           setInterpolator(interpolator).
           start();
Ramiah answered 27/7, 2015 at 12:8 Comment(6)
This is still rotate shadowAse
and introduce a strange shadow clipping too!Empiric
works ok with design support lib 23.2.0! no shadow rotation (tested on 6.0, 4.4). OvershootInterpolator is cool :)Brina
Tested with latest support lib 24.1.1 and its working fine. on Android 4.4.4 Samsung Neo, and Android 5.0.1 Micromax BoltTallou
How can I set the rotation of the icon within the fab, instead of animating it?Pfeffer
how to make this animation repeats?Efrainefram
S
21
public void rotateFabForward() {
    ViewCompat.animate(fab)
            .rotation(135.0F)
            .withLayer()
            .setDuration(300L)
            .setInterpolator(new OvershootInterpolator(10.0F))
            .start();
}

public void rotateFabBackward() {
    ViewCompat.animate(fab)
            .rotation(0.0F)
            .withLayer()
            .setDuration(300L)
            .setInterpolator(new OvershootInterpolator(10.0F))
            .start();
}
Stich answered 1/3, 2016 at 10:50 Comment(2)
This works nicely. How can I achieve the same, but without animation? Meaning I want to set the rotation right away?Pfeffer
set duration to 0LHeredity
A
5

Shortest way: For clockwise rotation:

fab.animate().rotationBy(135f) // 135f = 135 degree.

For anticlockwise rotation (reset to initial position):

fab.animate().rotationBy(-135f) // 135f = 135 degree.
Achaean answered 19/5, 2021 at 9:26 Comment(0)
S
4

There's an entirely another approach that works flawlessly for me (the one suggested in the accepted answer produces a clipped shadow on pre-L). Create an XML drawable and wrap your FAB icon into a <rotate> tag like this:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="45">
    <bitmap android:src="@drawable/ic_add_white_24dp"/>
</rotate>

Set this drawable to your FAB, and animate either its level directly or the imageLevel property of the FAB itself; it goes from 0 to 10000. If you'd like an OvershootInterpolator, then set toDegrees to 90 and animate the level up to the value of 5000 so it doesn't go beyond the bounds.

Sandoval answered 2/3, 2016 at 10:54 Comment(1)
side note: if drawable is vector, you cannot use bitmap, instead you might give it a try following: <rotate drawable="@drawable/ic_add_white_24dp" ...Cup
D
1

You can just rotate 45 degrees to get the cancel button effect on the tap of the fab button and rotate again -45 to get it normal.

binding?.fabAddPostMenu?.animate()?.rotationBy(45f)
Dieter answered 27/3, 2023 at 14:9 Comment(0)
H
-1

Same can be achieved via object animator:

  moveRight.rotation = -180f
Heredity answered 18/3, 2019 at 16:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.