Skip to content

Commit

Permalink
Disables StateListAnimator for React Slider Android 6 and 7
Browse files Browse the repository at this point in the history
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 facebook/react-native#9979

Reviewed By: yungsters

Differential Revision: D13404685

fbshipit-source-id: d4c4f8796664c890f6a6b3502d3493370e17c300
  • Loading branch information
mdvacca authored and facebook-github-bot committed Dec 11, 2018
1 parent 2e71a10 commit 4b3b667
Showing 1 changed file with 29 additions and 28 deletions.
57 changes: 29 additions & 28 deletions ReactSlider.java
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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()) {
Expand All @@ -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;
Expand All @@ -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() {
Expand Down

0 comments on commit 4b3b667

Please sign in to comment.