【问题标题】:Floating Action Button animation Issue浮动操作按钮动画问题
【发布时间】:2016-01-27 19:22:03
【问题描述】:

当我遇到这个问题时,我正在使用支持设计库中的晶圆厂。 我替换了 Android Studio 中默认的 Blank Activity 模板中的 onCreate 方法,如下所示:

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.animation.TranslateAnimation;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                anim.setDuration(1000);
                anim.setFillEnabled(true);
                anim.setFillAfter(true);
                fab.startAnimation(anim);
            }
        });
        fab.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                anim.setDuration(1000);
                anim.setFillEnabled(true);
                anim.setFillAfter(true);
                fab.startAnimation(anim);
                return true;
            }
        });
    }
}

所以基本上,我添加了一个 onClickListener 和一个 onLongClickListener,它们将 fab 翻译了 500idks,但问题是它不能像预期的那样工作。

当我点击它时,通常什么都不会发生,这开始时很奇怪。这是正在发生的video。

当我长按它时,它会像我应该的那样动画,但只有当我继续按下时,每当我抬起手指时,它都会回到原始位置,无论动画是否完成,即使我设置了@987654327 @ 和 setFillAfter(true)。

这里是当我lift我的手指和我leave我的手指在屏幕上直到最后和everything时发生的视频。

为什么会这样?

【问题讨论】:

  • 我觉得你应该声明FloatingActionButton fab是一个全局变量
  • @MrNeo 并没有什么不同
  • 我在 Nexus 4 上尝试过,版本为 5.1.1。它可以按您的预期工作,并且没有您在设置中看到的问题。
  • @lewis 我在 4.4.4 上对其进行了测试,根据源代码回退到不同的实现。所以我想这解决了一些谜团。感谢您的评论

标签: android android-animation


【解决方案1】:

我不知道您为什么会遇到这个动画问题,但它看起来像是一个错误。我检查了您的代码,它适用于我的 Android 6.0,但它不适用于搭载 Android 4.4 的 Android Emulator(但我的问题与您的问题有点不同)。

所以我假设这是一个错误,因为TranslateAnimation 有(并且可能仍然有)一些类似one、two 的错误。

接下来是我如何避免它的建议。使用ViewPropertyAnimator 为您的视图设置动画。在这种情况下,您的代码应如下所示:

    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            fab.animate()
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
        }
    });
    fab.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            fab.animate()
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
            return true;
        }
    });

我在带有 Android 4.3、4.4、5.0、6.0 的 Android Emulator 上进行了检查,它运行良好。

更新

为您找到解决方案。所以你可以使用支持库中的ViewPropertyAnimatorCompat,你的代码类似于:

fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
            ViewCompat.animate(fab)
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
    }
});
fab.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View view) {
            ViewCompat.animate(fab)
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
        return true;
    }
});

【讨论】:

  • 是的 ViewPropertyAnimator 也可以在我的设备上运行,但我想要一些适用于 api 11 的东西,并且 ViewPropertyAnimator 是在 12 中引入的。我也看起来你对这个错误也可能是对的
  • @Olumide,在这种情况下你可以尝试使用这个库github.com/JakeWharton/NineOldAndroids
  • @Olumide,为您找到解决方案,请参阅我的更新答案
  • ViewCompat 本来不错,但 documentation 说“在 API 14 之前,此方法将无济于事。”
  • 如我所说,来自 NineOldAndroids 的 ViewPropertyAnimator 怎么样? com.nineoldandroids.view.ViewPropertyAnimator.animate(fab).translationX(-500).translationY(-500).setDuration(1000).start(); 已检查,适用于 FAB
【解决方案2】:

更新:现在应该在我打开的错误之后在支持 lib 24.2.0 中修复:https://code.google.com/p/android/issues/detail?id=215043

==============

对于我们这些不够幸运,像我一样只用ViewPropertyAnimation 替换动画的人:

这个错误的发生是因为 FloatingActionButton 的支持实现中的错误,具体在 FloatingActionButtonEclairMr1 类中,其中将动画设置为所有视图状态,因此当单击视图时会触发 FloatingActionButtonEclairMr1.ElevateToTranslationZAnimation 动画,因此您的动画将从视图中清除。

我找到的最简单的解决方案是延迟启动动画,NOT 使用startOffset(因为它仍然会被按下动画覆盖)但调用动画有延迟(我使用的是 100,但也检查了 60 并且它有效。20 是不够的):

    final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Probably want to do it just for pre Lolipop
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                    anim.setDuration(1000);
                    anim.setFillEnabled(true);
                    anim.setFillAfter(true);
                    fab.startAnimation(anim);
                }
            }, 100);
        }
    });
    fab.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                    anim.setDuration(1000);
                    anim.setFillEnabled(true);
                    anim.setFillAfter(true);
                    fab.startAnimation(anim);
                }
            }, 100);
        }
    });

【讨论】:

    【解决方案3】:

    我认为您必须将 anim 对象保留为类级别变量,在许多情况下,onLongClick() 和 onClick() 会以重叠的方式调用。因为你有不同的动画对象,你最终会从两个动画对象访问同一个工厂。

    请在外面保持动画并发表您的观察。

    并尝试删除 onLongClick() 或 onClick() 方法。如果可能,请在这两种方法中添加日志以了解调用顺序。

    我会等待你的意见。

    【讨论】:

      【解决方案4】:

      也许这与您的问题有关:SO-Thread

      我正在使用 AnimatorListener 在完成动画后设置视图的位置。

      .addListener(new Animator.AnimatorListener() {
              @Override
              public void onAnimationStart(Animator animation) {
      
              }
      
              @Override
              public void onAnimationEnd(Animator animation) {
                  // set Position
              }
      
              @Override
              public void onAnimationCancel(Animator animation) {
      
              }
      
              @Override
              public void onAnimationRepeat(Animator animation) {
      
              }
          });
      

      我只看到了您的代码的摘录。对于您的 onClickListener 问题,我会检查您是否在 xml 中设置了 android:clickable="false" 或者您是否实现了另一个 OnClickListener。

      【讨论】:

      • 您提供的链接很有见地,但它并没有解释为什么我一抬起手指就会出现动画。我还更新了代码以包含所有内容
      【解决方案5】:

      您需要使用ViewPropertyAnimator 来完成这项工作。动画实际上并不移动视图本身,只是视图的位图表示,如here 所述。

      【讨论】:

        猜你喜欢
        • 2015-11-08
        • 2014-10-18
        • 1970-01-01
        • 2015-07-09
        • 1970-01-01
        • 1970-01-01
        • 2020-02-26
        • 2015-11-19
        • 2015-03-11
        相关资源
        最近更新 更多