Вы видите "Поле требует API 21". Ошибки в строке Studio для следующих строк кода, которые приложение прерывает при запуске на Lollipop.
ObjectAnimator translationZ = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, from, to);
ObjectAnimator translationZBack = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, to, from);
PathInterpolator pathInterpolator = new PathInterpolator(path);
Как вы знаете, эти функции были введены в API 21 инедоступно для более ранних API, и поэтому вы видите эти ошибки.Однако вы можете получить интерполятор пути из библиотеки поддержки, используя PathInterpolatorCompat .
Помощник для создания основанных на пути экземпляров [Interpolator](https://developer.android.com/reference/android/view/animation/Interpolator.html)
.На API 21 или новее будет использоваться реализация платформы, а на старых платформах будет использоваться совместимая альтернативная реализация.
Не думаю, что вам понадобится решение для перевода "z".(Я действительно не вижу никакой разницы между тем, иметь это и нет, но это может быть только я. В любом случае, у FAB уже есть тень для эффекта высоты.)
Вот переделка animFab()
с некоторыми изменениями для адаптации API до 21. Убедитесь, что вы извлекли PathInterpolatorCompat
из библиотеки поддержки v4. Сначала видео, показывающее код, работающий на эмуляторе API 19:
public void animFab() {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(fab, View.SCALE_X, from, to);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(fab, View.SCALE_Y, from, to);
AnimatorSet set1 = new AnimatorSet();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ObjectAnimator translationZ = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, from, to);
set1.playTogether(scaleX, scaleY, translationZ);
} else {
set1.playTogether(scaleX, scaleY);
}
set1.setDuration(500);
set1.setInterpolator(new AccelerateInterpolator());
set1.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
}
});
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);
Interpolator pathInterpolator = PathInterpolatorCompat.create(path);
AnimatorSet set2 = new AnimatorSet();
ObjectAnimator scaleXBack = ObjectAnimator.ofFloat(fab, View.SCALE_X, to, from);
ObjectAnimator scaleYBack = ObjectAnimator.ofFloat(fab, View.SCALE_Y, to, from);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ObjectAnimator translationZBack = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, to, from);
set2.playTogether(scaleXBack, scaleYBack, translationZBack);
} else {
set2.playTogether(scaleXBack, scaleYBack);
}
set2.setDuration(500);
set2.setInterpolator(pathInterpolator);
final AnimatorSet set = new AnimatorSet();
set.playSequentially(set1, set2);
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
set.start();
}
});
set.start();
}
Другая возможность заключается в использовании AnimatedVectorDrawableCompat для рисованной анимации, но это будет полное переписывание.