【问题标题】:Floating Action Button Animation浮动动作按钮动画
【发布时间】:2015-03-11 09:53:02
【问题描述】:

当一个 fab 出现时,它使用缩放动画制作动画,当它隐藏时,它使用缩放动画。

所以,它是一个放大和缩小的动画。

如何制作这个动画?

【问题讨论】:

    标签: android android-animation


    【解决方案1】:

    从@Zielony 的回答中,我做到了我想要的地方。

    以下是正确应用效果的代码。

    scale_fab_in.xml

    <?xml version="1.0" encoding="utf-8"?>
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:fromXScale="0"
        android:fromYScale="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1"
        android:interpolator="@android:interpolator/overshoot"/>
    

    scale_fab_out.xml

    <?xml version="1.0" encoding="utf-8"?>
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="400"
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0"
        android:toYScale="0"
        android:interpolator="@android:interpolator/overshoot"/>
    

    编辑 2/16/2016 - 另一种方法:

    将下面的代码放在您的 FAB 代码或任何其他视图中。

    //global
        private static final int FAB_ANIM_DURATION = 200;
    
    public void hide() {
            // Only use scale animation if FAB is visible
            if (getVisibility() == View.VISIBLE) {
                // Pivots indicate where the animation begins from
                float pivotX = getPivotX() + getTranslationX();
                float pivotY = getPivotY() + getTranslationY();
    
                // Animate FAB shrinking
                ScaleAnimation anim = new ScaleAnimation(1, 0, 1, 0, pivotX, pivotY);
                anim.setDuration(FAB_ANIM_DURATION);
                anim.setInterpolator(getInterpolator());
                startAnimation(anim);
            }
            setVisibility(View.INVISIBLE);
        }
    
    
        public void show() {
            show(0, 0);
        }
    
        public void show(float translationX, float translationY) {
    
            // Set FAB's translation
            setTranslation(translationX, translationY);
    
            // Only use scale animation if FAB is hidden
            if (getVisibility() != View.VISIBLE) {
                // Pivots indicate where the animation begins from
                float pivotX = getPivotX() + translationX;
                float pivotY = getPivotY() + translationY;
    
                ScaleAnimation anim;
                // If pivots are 0, that means the FAB hasn't been drawn yet so just use the
                // center of the FAB
                if (pivotX == 0 || pivotY == 0) {
                    anim = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f,
                            Animation.RELATIVE_TO_SELF, 0.5f);
                } else {
                    anim = new ScaleAnimation(0, 1, 0, 1, pivotX, pivotY);
                }
    
                // Animate FAB expanding
                anim.setDuration(FAB_ANIM_DURATION);
                anim.setInterpolator(getInterpolator());
                startAnimation(anim);
            }
            setVisibility(View.VISIBLE);
        }
    
        private void setTranslation(float translationX, float translationY) {
            if (Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) {
                animate().setInterpolator(getInterpolator()).setDuration(FAB_ANIM_DURATION)
                        .translationX(translationX).translationY(translationY);
            }
        }
    
        private Interpolator getInterpolator() {
            return AnimationUtils.loadInterpolator(getContext(), R.interpolator.fab_interpolator);
        }
    
    
    <item name="fab_interpolator" type="interpolator">@android:interpolator/decelerate_cubic</item>
    

    【讨论】:

    【解决方案2】:

    按钮只是使用 OvershootInterpolator 从 0 缩放到 1。应该是这样的:

    ScaleAnimation anim = new ScaleAnimation(0,1,0,1);
    anim.setFillBefore(true);
    anim.setFillAfter(true);
    anim.setFillEnabled(true);
    anim.setDuration(300);
    anim.setInterpolator(new OvershootInterpolator());
    fab.startAnimation(anim);
    

    http://developer.android.com/reference/android/view/animation/OvershootInterpolator.html

    【讨论】:

    • 它可以工作,但是放大动画从 FAB 的左侧开始,而不是从中心开始,任何想法如何解决它?
    • 你可以设置pivotX & pivotY来改变动画的中心点
    【解决方案3】:

    您可以使用此方法对任何视图进行动画放大。如果你反转 0 和 1,你会得到按比例缩小的动画

     public static void scale(View view, long delay) {
            view.setScaleX(0);
            view.setScaleY(0);
            view.animate()
                    .scaleX(1)
                    .scaleY(1)
                    .setDuration(500)
                    .setStartDelay(delay)
                    .setInterpolator(new OvershootInterpolator())
                    .start();
        }
    

    【讨论】:

      【解决方案4】:

      就我而言,这种类型的缩放动画在设置startOffset 值时看起来更好。这对我很有用:

      <scale xmlns:android="http://schemas.android.com/apk/res/android"
             android:duration="400"
             android:fillBefore="true"
             android:fillAfter="true"
             android:fillEnabled="true"
             android:startOffset="500"
             android:fromXScale="0"
             android:fromYScale="0"
             android:pivotX="50%"
             android:pivotY="50%"
             android:toXScale="1"
             android:toYScale="1"
             android:interpolator="@android:interpolator/overshoot"/>
      

      【讨论】:

        【解决方案5】:

        使用下面的代码可以得到同样的效果。

            ScaleAnimation anim = new ScaleAnimation(0, 1, 0, 1, 50, 50);
            anim.setFillBefore(true);
            anim.setFillAfter(true);
            anim.setFillEnabled(true);
            anim.setDuration(400);
            anim.setInterpolator(new OvershootInterpolator());
            imageView.startAnimation(anim);
        

        【讨论】:

          【解决方案6】:

          假设请求是为 FloatingActionButton 调整大小设置动画,我首先将 Animation 子类化为一般处理 View(改编自 @987654321 的 Kotlin @)...

          open class ResizeAnimation(
              private val view: View,
              private val toHeight: Float,
              private val fromHeight: Float,
              private val toWidth: Float,
              private val fromWidth: Float,
              duration: Long
          ) : Animation() {
          
              init {
                  this.duration = duration
              }
          
              override fun applyTransformation(
                  interpolatedTime: Float,
                  t: Transformation?
              ) {
                  val height = (toHeight - fromHeight) * interpolatedTime + fromHeight
                  val width = (toWidth - fromWidth) * interpolatedTime + fromWidth
                  val layoutParams = view.layoutParams
                  layoutParams.height = height.toInt()
                  layoutParams.width = width.toInt()
                  view.requestLayout()
              }
          }
          

          ...为了处理 FloatingActionButton,我将 _ResizeAnimation_ 子类化(主要是为了更新浮动操作按钮的 customSize 属性)...

          class FabResizeAnimation(
              private val view: FloatingActionButton,
              private val toSize: Float,
              private val fromSize: Float,
              duration: Long
          ) : ResizeAnimation(
              view,
              toSize,
              fromSize,
              toSize,
              fromSize,
              duration
          ) {
          
              override fun applyTransformation(
                  interpolatedTime: Float,
                  t: Transformation?
              ) {
                  val fabSize = ((toSize - fromSize) * interpolatedTime + fromSize).toInt()
                  view.customSize = fabSize
                  super.applyTransformation(interpolatedTime, t)
              }
          }
          

          ...用法...

              val animation = FabResizeAnimation(fab, 800.0f, 100.0f, 2000)
              fab.startAnimation(animation)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-11-08
            • 1970-01-01
            • 1970-01-01
            • 2015-07-09
            • 1970-01-01
            • 2015-11-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多