【问题标题】:Animating Fab on click (zoom in/out)单击动画 Fab(放大/缩小)
【发布时间】:2017-04-06 17:03:08
【问题描述】:

我正在尝试为以下浮动操作按钮模拟动画和颜色变化。

浮动操作按钮的工作方式是白色关闭,蓝色打开。

但是,我在动画和更改颜色方面没有成功。

这些是我的尝试,如您所见,我已经注释掉了我尝试执行此操作的所有不同方式。

这是我的代码:

    @SuppressWarnings("unused")
    @OnClick(R.id.fabMovieFavourite)
    public void addMovieFavourite(View view) {
 /*       final Animator animator = AnimatorInflater.loadAnimator(getActivity(), R.animator.add_favourite_movie);
        animator.setTarget(view);)
        animator.start();
 */
/*
        AnimatorSet animatorSet = new AnimatorSet();
        PropertyValuesHolder propertyValuesHolderX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1.1f);
        PropertyValuesHolder propertyValuesHolderY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.1f);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, propertyValuesHolderX, propertyValuesHolderY);
        objectAnimator.setDuration(300);
        objectAnimator.setInterpolator(new OvershootInterpolator(10f));
*/

        /*
        objectAnimator.setRepeatCount(1);
        objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);
*/

/*
        PropertyValuesHolder propertyValuesHolderX2 = PropertyValuesHolder.ofFloat(View.SCALE_X, 0.9f);
        PropertyValuesHolder propertyValuesHolderY2 = PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.9f);
        ObjectAnimator objectAnimator2 = ObjectAnimator.ofPropertyValuesHolder(view, propertyValuesHolderX2, propertyValuesHolderY2);
        objectAnimator.setDuration(300);
        objectAnimator2.setInterpolator(new OvershootInterpolator(10f));

        animatorSet.playSequentially(objectAnimator, objectAnimator2);
        objectAnimator.start();
*/

      //  view.BackgroundTintList(ContextCompat.getColorStateList(getContext(), R.color.primary));
        //view.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.primary));

        if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            Timber.d("start translationZ");
            ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Z, 12f);
            objectAnimator.setDuration(300);
            objectAnimator.setInterpolator(new OvershootInterpolator(10f));
            objectAnimator.setTarget(view);
            objectAnimator.start();
        }
    }

非常感谢您的任何建议。

【问题讨论】:

  • 我会尝试使用两个 FAB。淡出并隐藏一个,淡入并显示另一个。
  • @AngelKoh 我正在寻找仅使用 1 个晶圆厂的解决方案
  • @ant2009 好吧,我已经在库 github.com/jd-alexander/LikeButton 的帮助下实现了这个目标,如果你想实现这个......我可以帮忙......它......
  • @PN10 谢谢,我去看看

标签: java android animation android-animation floating-action-button


【解决方案1】:

这个动画有两个阶段。第一个缩放 X 和 Y 轴,第二个缩放它。所以,我们可以把它们分成两个AnimatorSets,依次播放。

动画的重点是为第二个AnimatorSet找到合适的插值器,因为它不是标准的。

看,我们希望 fab 过冲,然后下冲,最后稳定到动画器中的指定值。

幸运的是,PathInterpolator 非常方便,它将为我们创建一个插值器,并提供 Path

Path path = new Path();
path.moveTo(0.0f, 0.0f);
path.lineTo(0.5f, 1.3f);
path.lineTo(0.75f, 0.8f);
path.lineTo(1.0f, 1.0f);
PathInterpolator pathInterpolator = new PathInterpolator(path);

那么,让我们创建第一个动画:

final float from = 1.0f;
final float to = 1.3f;

ObjectAnimator scaleX = ObjectAnimator.ofFloat(fab, View.SCALE_X, from, to);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(fab, View.SCALE_Y,  from, to);
ObjectAnimator translationZ = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, from, to);

AnimatorSet set1 = new AnimatorSet();
set1.playTogether(scaleX, scaleY, translationZ);
set1.setDuration(100);
set1.setInterpolator(new AccelerateInterpolator());

set1.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        fab.setImageResource(isActive ? R.drawable.heart_active : R.drawable.heart_passive);
        fab.setBackgroundTintList(ColorStateList.valueOf(isActive ? colorActive : colorPassive));
        isActive = !isActive;
    }
});

我们同时缩放 x、y。此外,我们正在更改 z 平移以具有适当的阴影效果。当动画结束时,我们想要改变 fab 的状态(心的颜色和 fab 背景的颜色)。

现在让我们创建动画来安顿下来:

ObjectAnimator scaleXBack = ObjectAnimator.ofFloat(fab, View.SCALE_X, to, from);
ObjectAnimator scaleYBack = ObjectAnimator.ofFloat(fab, View.SCALE_Y, to, from);
ObjectAnimator translationZBack = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, to, from);

AnimatorSet set2 = new AnimatorSet();
set2.playTogether(scaleXBack, scaleYBack, translationZBack);
set2.setDuration(300);
set2.setInterpolator(pathInterpolator);

请看这里,我们使用了之前创建的pathInterpolator

我们想依次播放这两个AnimatorSets:

final AnimatorSet set = new AnimatorSet();
set.playSequentially(set1, set2);

set.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        fab.setClickable(true);
    }

    @Override
    public void onAnimationStart(Animator animation) {
        fab.setClickable(false);
    }
});

此外,我们希望在制作动画时禁用对 fab 的点击。所以我们根据动画状态打开/关闭它。

最后,我们在点击发生时启动动画:

fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        set.start();
    }
});

结果:

Source code at github

【讨论】:

  • 我见过的设置动画的最佳细分之一,如果不是的话。感谢您花这么多时间来回答这个问题,这对您有很大帮助。
  • 嘿@azizbekian 你能帮我解决这个stackoverflow.com/questions/53577838/… 上面的代码在lolipop 及以上设备上运行良好,但在kitkat 中不起作用
猜你喜欢
  • 2019-05-03
  • 2021-12-10
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 1970-01-01
  • 2011-10-19
  • 2013-05-23
相关资源
最近更新 更多