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
This commit is contained in:
David Vacca 2018-12-11 11:18:56 -08:00 committed by Facebook Github Bot
parent 39b6890346
commit aeaeac88f8

View File

@ -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.
* <p>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.
* <p>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).
* <p>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 class ReactSlider extends SeekBar {
}
/**
* 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 class ReactSlider extends SeekBar {
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 @@ public class ReactSlider extends SeekBar {
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() {