From 4b3b667e0acfb4db2d506472b1c9a93a52c60aa6 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 11 Dec 2018 11:18:56 -0800 Subject: [PATCH] Disables StateListAnimator for React Slider Android 6 and 7 Summary: This diff disables the StateListAnimator for the ReactSlider component in Android 6 and 7 This is this is a hack to prevent T37452851 and https://github.com/facebook/react-native/issues/9979 Reviewed By: yungsters Differential Revision: D13404685 fbshipit-source-id: d4c4f8796664c890f6a6b3502d3493370e17c300 --- ReactSlider.java | 57 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/ReactSlider.java b/ReactSlider.java index 5d2e39bb..eddc7241 100644 --- a/ReactSlider.java +++ b/ReactSlider.java @@ -1,57 +1,64 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + *

This source code is licensed under the MIT license found in the LICENSE file in the root + * directory of this source tree. */ - package com.facebook.react.views.slider; import android.content.Context; +import android.os.Build; import android.util.AttributeSet; import android.widget.SeekBar; - import javax.annotation.Nullable; /** * Slider that behaves more like the iOS one, for consistency. * - * On iOS, the value is 0..1. Android SeekBar only supports integer values. - * For consistency, we pretend in JS that the value is 0..1 but set the - * SeekBar value to 0..100. + *

On iOS, the value is 0..1. Android SeekBar only supports integer values. For consistency, we + * pretend in JS that the value is 0..1 but set the SeekBar value to 0..100. * - * Note that the slider is _not_ a controlled component (setValue isn't called - * during dragging). + *

Note that the slider is _not_ a controlled component (setValue isn't called during dragging). */ public class ReactSlider extends SeekBar { /** - * If step is 0 (unset) we default to this total number of steps. - * Don't use 100 which leads to rounding errors (0.200000000001). + * If step is 0 (unset) we default to this total number of steps. Don't use 100 which leads to + * rounding errors (0.200000000001). */ private static int DEFAULT_TOTAL_STEPS = 128; /** - * We want custom min..max range. - * Android only supports 0..max range so we implement this ourselves. + * We want custom min..max range. Android only supports 0..max range so we implement this + * ourselves. */ private double mMinValue = 0; + private double mMaxValue = 0; /** - * Value sent from JS (setState). - * Doesn't get updated during drag (slider is not a controlled component). + * Value sent from JS (setState). Doesn't get updated during drag (slider is not a controlled + * component). */ private double mValue = 0; - /** - * If zero it's determined automatically. - */ + /** If zero it's determined automatically. */ private double mStep = 0; + private double mStepCalculated = 0; public ReactSlider(Context context, @Nullable AttributeSet attrs, int style) { super(context, attrs, style); + disableStateListAnimatorIfNeeded(); + } + + private void disableStateListAnimatorIfNeeded() { + // We disable the state list animator for Android 6 and 7; this is a hack to prevent T37452851 + // and https://github.com/facebook/react-native/issues/9979 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + super.setStateListAnimator(null); + } } /* package */ void setMaxValue(double max) { @@ -75,8 +82,7 @@ public ReactSlider(Context context, @Nullable AttributeSet attrs, int style) { } /** - * Convert SeekBar's native progress value (e.g. 0..100) to a value - * passed to JS (e.g. -1.0..2.5). + * Convert SeekBar's native progress value (e.g. 0..100) to a value passed to JS (e.g. -1.0..2.5). */ public double toRealProgress(int seekBarProgress) { if (seekBarProgress == getMax()) { @@ -85,9 +91,7 @@ public double toRealProgress(int seekBarProgress) { return seekBarProgress * getStepValue() + mMinValue; } - /** - * Update underlying native SeekBar's values. - */ + /** Update underlying native SeekBar's values. */ private void updateAll() { if (mStep == 0) { mStepCalculated = (mMaxValue - mMinValue) / (double) DEFAULT_TOTAL_STEPS; @@ -96,12 +100,9 @@ private void updateAll() { updateValue(); } - /** - * Update value only (optimization in case only value is set). - */ + /** Update value only (optimization in case only value is set). */ private void updateValue() { - setProgress((int) Math.round( - (mValue - mMinValue) / (mMaxValue - mMinValue) * getTotalSteps())); + setProgress((int) Math.round((mValue - mMinValue) / (mMaxValue - mMinValue) * getTotalSteps())); } private int getTotalSteps() {