mirror of
https://github.com/material-components/material-components-android.git
synced 2026-02-20 08:39:55 +08:00
Support design - fix FAB elevation in API 21
The animations are really broken here. A hacky fix has been added in the past for versions 22-24 and now for version 21 just by bluntly set the elevation and translationZ by respecting the logic in the animations for 22-24. Bug: 33126409 Test: identified this bug from an existing test. Change-Id: I0cba73cda030ef7a66ffad452bc0f14b7687fc52 GitOrigin-RevId=829c95c8a3fd508b798bedff028d7d6b55e16ce5 PiperOrigin-RevId: 141514172
This commit is contained in:
parent
68a3946982
commit
24b2fc718a
@ -28,6 +28,7 @@ import android.graphics.drawable.GradientDrawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||
import android.view.View;
|
||||
@ -81,48 +82,64 @@ class FloatingActionButtonLollipop extends FloatingActionButtonIcs {
|
||||
|
||||
@Override
|
||||
void onElevationsChanged(final float elevation, final float pressedTranslationZ) {
|
||||
final StateListAnimator stateListAnimator = new StateListAnimator();
|
||||
final int sdk = Build.VERSION.SDK_INT;
|
||||
if (sdk == 21) {
|
||||
// Animations produce NPE in version 21. Bluntly set the values instead (matching the
|
||||
// logic in the animations below).
|
||||
if (mView.isEnabled()) {
|
||||
mView.setElevation(elevation);
|
||||
if (mView.isFocused() || mView.isPressed()) {
|
||||
mView.setTranslationZ(pressedTranslationZ);
|
||||
} else {
|
||||
mView.setTranslationZ(0);
|
||||
}
|
||||
} else {
|
||||
mView.setElevation(0);
|
||||
mView.setTranslationZ(0);
|
||||
}
|
||||
} else {
|
||||
final StateListAnimator stateListAnimator = new StateListAnimator();
|
||||
|
||||
// Animate elevation and translationZ to our values when pressed
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
set.play(ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0))
|
||||
.with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, pressedTranslationZ)
|
||||
.setDuration(PRESSED_ANIM_DURATION));
|
||||
set.setInterpolator(ANIM_INTERPOLATOR);
|
||||
stateListAnimator.addState(PRESSED_ENABLED_STATE_SET, set);
|
||||
// Animate elevation and translationZ to our values when pressed
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
set.play(ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0))
|
||||
.with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, pressedTranslationZ)
|
||||
.setDuration(PRESSED_ANIM_DURATION));
|
||||
set.setInterpolator(ANIM_INTERPOLATOR);
|
||||
stateListAnimator.addState(PRESSED_ENABLED_STATE_SET, set);
|
||||
|
||||
// Same deal for when we're focused
|
||||
set = new AnimatorSet();
|
||||
set.play(ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0))
|
||||
.with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, pressedTranslationZ)
|
||||
.setDuration(PRESSED_ANIM_DURATION));
|
||||
set.setInterpolator(ANIM_INTERPOLATOR);
|
||||
stateListAnimator.addState(FOCUSED_ENABLED_STATE_SET, set);
|
||||
// Same deal for when we're focused
|
||||
set = new AnimatorSet();
|
||||
set.play(ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0))
|
||||
.with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, pressedTranslationZ)
|
||||
.setDuration(PRESSED_ANIM_DURATION));
|
||||
set.setInterpolator(ANIM_INTERPOLATOR);
|
||||
stateListAnimator.addState(FOCUSED_ENABLED_STATE_SET, set);
|
||||
|
||||
// Animate translationZ to 0 if not pressed
|
||||
set = new AnimatorSet();
|
||||
set.playSequentially(
|
||||
ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0),
|
||||
// This is a no-op animation which exists here only for introducing the duration
|
||||
// because setting the delay (on the next animation) via "setDelay" or "after" can
|
||||
// trigger a NPE between android versions 21 and 24 (due to a framework bug). The
|
||||
// issue has been fixed in version 25.
|
||||
ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, mView.getTranslationZ())
|
||||
.setDuration(PRESSED_ANIM_DELAY),
|
||||
ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, 0f)
|
||||
.setDuration(PRESSED_ANIM_DURATION));
|
||||
// Animate translationZ to 0 if not pressed
|
||||
set = new AnimatorSet();
|
||||
set.playSequentially(
|
||||
ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0),
|
||||
// This is a no-op animation which exists here only for introducing the duration
|
||||
// because setting the delay (on the next animation) via "setDelay" or "after"
|
||||
// can trigger a NPE between android versions 22 and 24 (due to a framework
|
||||
// bug). The issue has been fixed in version 25.
|
||||
ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, mView.getTranslationZ())
|
||||
.setDuration(PRESSED_ANIM_DELAY),
|
||||
ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, 0f)
|
||||
.setDuration(PRESSED_ANIM_DURATION));
|
||||
set.setInterpolator(ANIM_INTERPOLATOR);
|
||||
stateListAnimator.addState(ENABLED_STATE_SET, set);
|
||||
|
||||
set.setInterpolator(ANIM_INTERPOLATOR);
|
||||
stateListAnimator.addState(ENABLED_STATE_SET, set);
|
||||
// Animate everything to 0 when disabled
|
||||
set = new AnimatorSet();
|
||||
set.play(ObjectAnimator.ofFloat(mView, "elevation", 0f).setDuration(0))
|
||||
.with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, 0f).setDuration(0));
|
||||
set.setInterpolator(ANIM_INTERPOLATOR);
|
||||
stateListAnimator.addState(EMPTY_STATE_SET, set);
|
||||
|
||||
// Animate everything to 0 when disabled
|
||||
set = new AnimatorSet();
|
||||
set.play(ObjectAnimator.ofFloat(mView, "elevation", 0f).setDuration(0))
|
||||
.with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, 0f).setDuration(0));
|
||||
set.setInterpolator(ANIM_INTERPOLATOR);
|
||||
stateListAnimator.addState(EMPTY_STATE_SET, set);
|
||||
|
||||
mView.setStateListAnimator(stateListAnimator);
|
||||
mView.setStateListAnimator(stateListAnimator);
|
||||
}
|
||||
|
||||
if (mShadowViewDelegate.isCompatPaddingEnabled()) {
|
||||
updatePadding();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user