Rotating floating control

I believe most of you saw the spinning FloatingActionButton in apps like Google, hit the bullet and even the Google inbox app. I am trying to achieve this rotation by having an animation file that:

<?xml version="1.0" encoding="UTF-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="135" android:pivotX="50%" android:pivotY="50%" android:repeatCount="0" android:fillAfter="true" android:fillEnabled="true" android:duration="100" /> 

I am now using the makovkastar library to create this FAB button. However, when I set the FAB to rotate, the shadow rotates with the FAB button.

Is there a way to just animate the popped out FAB button inside?

This is how I set up the animation

  Animation anim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate); fab.startAnimation(anim); 
0
android rotation android-drawable android-animation floating-action-button
source share
2 answers

Yes ... what you need to do is turn the mActionIcon into a FloatingActionButtonClass. See below.

  public void applyRotation(float start, float end, final int imgRes) { final float centerX = getWidth() / 2.0f; final float centerY = getHeight() / 2.0f; // The animation listener is used to trigger the next animation final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, 0, true); rotation.setDuration(100); rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateInterpolator()); rotation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mActionIcon = getResources().getDrawable(imgRes); mActionIcon.setBounds(0, 0, mActionSize, mActionSize); // invalidate(); rotateSecondImage(-45, 0); } }); startAnimation(rotation); } private void rotateSecondImage(float start, float end) { final float centerX = getWidth() / 2.0f; final float centerY = getHeight() / 2.0f; // The animation listener is used to trigger the next animation final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, 0, true); rotation.setDuration(100); rotation.setFillAfter(true); rotation.setInterpolator(new DecelerateInterpolator()); startAnimation(rotation); } public class Rotate3dAnimation extends Animation { private final float mFromDegrees; private final float mToDegrees; private final float mCenterX; private final float mCenterY; private final float mDepthZ; private final boolean mReverse; private Camera mCamera; public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) { mFromDegrees = fromDegrees; mToDegrees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthZ = depthZ; mReverse = reverse; } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); mCamera = new Camera(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); camera.save(); if (mReverse) { camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } camera.rotateZ(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } 

}

0
source share

I found that on pre-Lollipop the shadow rotates, but on API> = 21 everything is correct.

So, on pre-Lollipop, I tried to rotate ImageView on top of FAB. And it works great.

Here is the layout where we place the ImageView with the same source image above the FAB:

 <FrameLayout> android:id="@+id/rotatingFab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end"> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:src="@drawable/ic_autorenew_white_24dp"/> <ImageView android:id="@+id/fabImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@color/accent" android:src="@drawable/ic_autorenew_white_24dp" android:visibility="gone"/> </FrameLayout> 

We start the animation as follows:

 public void startAnimation(Animation animation) { if (Build.VERSION.SDK_INT >= 21) { mFab.startAnimation(animation); } else { mFabImage.setVisibility(VISIBLE); // need post() to image could measure its size mFabImage.post(() -> mFabImage.startAnimation(animation)); } } 

And stop it:

 public void clearAnimation() { if (Build.VERSION.SDK_INT >= 21) { mFab.clearAnimation(); } else { mFabImage.clearAnimation(); mFabImage.setVisibility(GONE); } } 

I exchange FrameLayout in user view more comfortably, here is the full text https://gist.github.com/pengrad/9db82de705b58b10c5e9

0
source share

All Articles