浮动动作按钮动画问题

时间:2016-01-27 19:22:03

标签: android android-animation

当我运行此问题时,我正在支持设计库中使用fab。 我在Android Studio的默认空白活动模板中替换了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发生的事情。

当我长按它时,它会像我应该的那样动画,但只有当我一直按下时,每当我抬起手指时,无论动画是否完整,它都会回到原始位置,即使我设置了{{ 1}}和setFillEnabled(true)

以下是当我lift我的手指以及当我leave我的手指在屏幕上直到最后everything时会发生什么的视频。

Animation

为什么会这样?

5 个答案:

答案 0 :(得分:6)

我不知道你为什么会遇到这个动画问题,但它看起来像个bug。我检查了你的代码并且它适用于我的Android 6.0,但它不适用于安装了Android 4.4的Android模拟器(但我的问题与你的有点不同)。

所以我的假设是一个错误,因为TranslateAnimation有(可能还有)像onetwo这样的错误。

我的建议是如何避免接下来的。使用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模拟器上使用Android 4.3,4.4,5.0,6.0进行了检查,效果很好。

<强>更新

为您找到解决方案。因此,您可以使用支持库中的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;
    }
});

答案 1 :(得分:3)

更新:我现在假设在我已经打开的错误后修复了支持lib 24.2.0:https://code.google.com/p/android/issues/detail?id=215043

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

对于我们这些不够幸运的人来说,像我这样的ViewPropertyAnimation替换他们的动画:

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

我找到的最简单的解决方案就是以一些延迟开始你的动画,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);
        }
    });

答案 2 :(得分:2)

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

请保持在外面的动画并发布您的观察结果。

并尝试删除onLongClick()或onClick()方法。如果可能的话,在这两个方法中添加log以理解调用顺序。

我将等待您的观察。

答案 3 :(得分:1)

这可能与您的问题有关: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。

答案 4 :(得分:1)

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