Skip to content

Commit a718fd1

Browse files
cketchamdsn5ft
authored andcommitted
Add workaround to prevent FloatingActionButton crash on API 26.
Resolves #66 PiperOrigin-RevId: 284999697 (cherry picked from commit 3c3ac61)
1 parent 267d79f commit a718fd1

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

lib/java/com/google/android/material/floatingactionbutton/FloatingActionButtonImpl.java

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import android.animation.Animator.AnimatorListener;
2525
import android.animation.AnimatorListenerAdapter;
2626
import android.animation.AnimatorSet;
27+
import android.animation.FloatEvaluator;
2728
import android.animation.ObjectAnimator;
2829
import android.animation.TimeInterpolator;
30+
import android.animation.TypeEvaluator;
2931
import android.animation.ValueAnimator;
3032
import android.content.res.ColorStateList;
3133
import android.graphics.Color;
@@ -559,22 +561,23 @@ private MotionSpec getDefaultHideMotionSpec() {
559561
private AnimatorSet createAnimator(
560562
@NonNull MotionSpec spec, float opacity, float scale, float iconScale) {
561563
List<Animator> animators = new ArrayList<>();
562-
Animator animator;
563564

564-
animator = ObjectAnimator.ofFloat(view, View.ALPHA, opacity);
565-
spec.getTiming("opacity").apply(animator);
566-
animators.add(animator);
565+
ObjectAnimator animatorOpacity = ObjectAnimator.ofFloat(view, View.ALPHA, opacity);
566+
spec.getTiming("opacity").apply(animatorOpacity);
567+
animators.add(animatorOpacity);
567568

568-
animator = ObjectAnimator.ofFloat(view, View.SCALE_X, scale);
569-
spec.getTiming("scale").apply(animator);
570-
animators.add(animator);
569+
ObjectAnimator animatorScaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scale);
570+
spec.getTiming("scale").apply(animatorScaleX);
571+
workAroundOreoBug(animatorScaleX);
572+
animators.add(animatorScaleX);
571573

572-
animator = ObjectAnimator.ofFloat(view, View.SCALE_Y, scale);
573-
spec.getTiming("scale").apply(animator);
574-
animators.add(animator);
574+
ObjectAnimator animatorScaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scale);
575+
spec.getTiming("scale").apply(animatorScaleY);
576+
workAroundOreoBug(animatorScaleY);
577+
animators.add(animatorScaleY);
575578

576579
calculateImageMatrixFromScale(iconScale, tmpMatrix);
577-
animator =
580+
ObjectAnimator animatorIconScale =
578581
ObjectAnimator.ofObject(
579582
view,
580583
new ImageMatrixProperty(),
@@ -589,14 +592,33 @@ public Matrix evaluate(
589592
}
590593
},
591594
new Matrix(tmpMatrix));
592-
spec.getTiming("iconScale").apply(animator);
593-
animators.add(animator);
595+
spec.getTiming("iconScale").apply(animatorIconScale);
596+
animators.add(animatorIconScale);
594597

595598
AnimatorSet set = new AnimatorSet();
596599
AnimatorSetCompat.playTogether(set, animators);
597600
return set;
598601
}
599602

603+
/**
604+
* There appears to be a bug in the OpenGL shadow rendering code on API 26. We can work around it
605+
* by preventing any scaling close to 0.
606+
*/
607+
private void workAroundOreoBug(final ObjectAnimator animator) {
608+
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O) {
609+
return;
610+
}
611+
612+
animator.setEvaluator(new TypeEvaluator<Float>() {
613+
FloatEvaluator floatEvaluator = new FloatEvaluator();
614+
@Override
615+
public Float evaluate(float fraction, Float startValue, Float endValue) {
616+
float evaluated = floatEvaluator.evaluate(fraction, startValue, endValue);
617+
return evaluated < 0.1f ? 0.0f : evaluated;
618+
}
619+
});
620+
}
621+
600622
void addTransformationCallback(@NonNull InternalTransformationCallback listener) {
601623
if (transformationCallbacks == null) {
602624
transformationCallbacks = new ArrayList<>();

0 commit comments

Comments
 (0)