如何 hide/reveal 对同一个 FloatingActionButton 的不同操作,就像在收件箱应用程序中一样

How to hide/reveal different actions on the same FloatingActionButton like in Inbox app

有什么方法可以使支持库中的 FloatingActionButton 中的图标具有动画效果?我想像在收件箱应用程序中一样对其进行动画处理,当您单击它时,它会从 plus 转换为 pencil

最好的方法可能是使用 AnimatedVectorDrawable 但这在 5.0 之前不向后兼容。我通常只是将两个 FloatingActionButton 放在彼此的顶部,然后在旋转两个的同时淡出顶部的那个。

例如,您可以将两个 FloatingActionButton 放入一个 FrameLayout 中,如下所示:

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="16dp"
    android:layout_gravity="bottom|end|right">

    <android.support.design.widget.FloatingActionButton
        android:id="@id/fab_edit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_edit"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_add"/>

</FrameLayout>

FrameLayout 中的底部 FloatingActionButton 将位于另一个的顶部。然后您可以旋转并淡出底部的,同时旋转顶部的以创建类似于 Google 应用程序中的动画的动画,该动画将显示顶部的。例如,您可以像这样实现动画:

// This animation rotates and hides the top Button
final Animator hideTopFabAnimation = ObjectAnimator.ofPropertyValuesHolder(fabAdd,
        PropertyValuesHolder.ofFloat(View.ALPHA, 1.0f, 0.0f),
        PropertyValuesHolder.ofFloat(View.ROTATION, 0.0f, 360.0f)
);

// This animation just rotates the bottom Button while it is being revealed
final Animator revealBottomFabAnimation = ObjectAnimator.ofPropertyValuesHolder(fabEdit,
        PropertyValuesHolder.ofFloat(View.ROTATION, 0.0f, 360.0f)
);

// This AnimatorSet combines both animations and also has a listener 
// attached to set the visibility of the top Button to View.GONE when
// the animation is done so the user can actually click through to the 
// lower Button
final AnimatorSet revealAnimation = new AnimatorSet();
revealAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
revealAnimation.playTogether(
        hideTopFabAnimation,
        revealBottomFabAnimation
);
revealAnimation.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        fabAdd.setVisibility(View.GONE);
    }
});
revealAnimation.start();

要返回原始状态,您只需执行相反的操作即可:

// Set the visibility of the top Button back to VISIBLE
fabAdd.setVisibility(View.VISIBLE);

// This animation fades the top Button back in and rotates it back
final Animator showTopFabAnimation = ObjectAnimator.ofPropertyValuesHolder(fabAdd,
        PropertyValuesHolder.ofFloat(View.ALPHA, 0.0f, 1.0f),
        PropertyValuesHolder.ofFloat(View.ROTATION, 360.0f, 0.0f)
);

// This animation just rotates the bottom Button while the top Button 
// fades back in
final Animator hideBottomFabAnimation = ObjectAnimator.ofPropertyValuesHolder(fabEdit,
        PropertyValuesHolder.ofFloat(View.ROTATION, 360.0f, 0.0f)
);

// Again we have an AnimatorSet which plays both animations together
final AnimatorSet hideAnimation = new AnimatorSet();
revealAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
revealAnimation.playTogether(
        showTopFabAnimation,
        hideBottomFabAnimation
);
revealAnimation.start();