mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-06-19 21:29:36 +08:00
Revert D13860038: [react-native][PR] Add ability to control scroll animation duration for Android
Differential Revision: D13860038 Original commit changeset: f06751d063a3 fbshipit-source-id: 5d89137aed0d549004e790068c1e4998ebccdaf1
This commit is contained in:
committed by
Facebook Github Bot
parent
c16fadb7c3
commit
4c69ccd0fb
@@ -116,14 +116,6 @@ export type State = {|
|
||||
becameResponderWhileAnimating: boolean,
|
||||
|};
|
||||
|
||||
/**
|
||||
* If a user has specified a duration, we will use it. Otherwise,
|
||||
* set it to -1 as the bridge cannot handle undefined / null values.
|
||||
*/
|
||||
function getDuration(duration?: number): number {
|
||||
return duration === undefined ? -1 : Math.max(duration, 0);
|
||||
}
|
||||
|
||||
const ScrollResponderMixin = {
|
||||
_subscriptionKeyboardWillShow: (null: ?EmitterSubscription),
|
||||
_subscriptionKeyboardWillHide: (null: ?EmitterSubscription),
|
||||
@@ -432,55 +424,46 @@ const ScrollResponderMixin = {
|
||||
* This is currently used to help focus child TextViews, but can also
|
||||
* be used to quickly scroll to any element we want to focus. Syntax:
|
||||
*
|
||||
* `scrollResponderScrollTo(options: {x: number = 0; y: number = 0; animated: boolean = true, duration: number = 0})`
|
||||
* `scrollResponderScrollTo(options: {x: number = 0; y: number = 0; animated: boolean = true})`
|
||||
*
|
||||
* Note: The weird argument signature is due to the fact that, for historical reasons,
|
||||
* the function also accepts separate arguments as as alternative to the options object.
|
||||
* This is deprecated due to ambiguity (y before x), and SHOULD NOT BE USED.
|
||||
*/
|
||||
scrollResponderScrollTo: function(
|
||||
x?:
|
||||
| number
|
||||
| {x?: number, y?: number, animated?: boolean, duration?: number},
|
||||
x?: number | {x?: number, y?: number, animated?: boolean},
|
||||
y?: number,
|
||||
animated?: boolean,
|
||||
duration?: number,
|
||||
) {
|
||||
if (typeof x === 'number') {
|
||||
console.warn(
|
||||
'`scrollResponderScrollTo(x, y, animated)` is deprecated. Use `scrollResponderScrollTo({x: 5, y: 5, animated: true})` instead.',
|
||||
);
|
||||
} else {
|
||||
({x, y, animated, duration} = x || {});
|
||||
({x, y, animated} = x || {});
|
||||
}
|
||||
UIManager.dispatchViewManagerCommand(
|
||||
nullthrows(this.scrollResponderGetScrollableNode()),
|
||||
UIManager.getViewManagerConfig('RCTScrollView').Commands.scrollTo,
|
||||
[x || 0, y || 0, animated !== false, getDuration(duration)],
|
||||
[x || 0, y || 0, animated !== false],
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Scrolls to the end of the ScrollView, either immediately or with a smooth
|
||||
* animation. For Android, you may specify a "duration" number instead of the
|
||||
* "animated" boolean.
|
||||
* animation.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* `scrollResponderScrollToEnd({animated: true})`
|
||||
* or for Android, you can do:
|
||||
* `scrollResponderScrollToEnd({duration: 500})`
|
||||
*/
|
||||
scrollResponderScrollToEnd: function(options?: {
|
||||
animated?: boolean,
|
||||
duration?: number,
|
||||
}) {
|
||||
scrollResponderScrollToEnd: function(options?: {animated?: boolean}) {
|
||||
// Default to true
|
||||
const animated = (options && options.animated) !== false;
|
||||
UIManager.dispatchViewManagerCommand(
|
||||
this.scrollResponderGetScrollableNode(),
|
||||
UIManager.getViewManagerConfig('RCTScrollView').Commands.scrollToEnd,
|
||||
[animated, getDuration(options && options.duration)],
|
||||
[animated],
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
@@ -695,29 +695,20 @@ class ScrollView extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls to a given x, y offset, either immediately, with a smooth animation, or,
|
||||
* for Android only, a custom animation duration time.
|
||||
* Scrolls to a given x, y offset, either immediately or with a smooth animation.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* `scrollTo({x: 0, y: 0, animated: true})`
|
||||
*
|
||||
* Example with duration (Android only):
|
||||
*
|
||||
* `scrollTo({x: 0, y: 0, duration: 500})`
|
||||
*
|
||||
* Note: The weird function signature is due to the fact that, for historical reasons,
|
||||
* the function also accepts separate arguments as an alternative to the options object.
|
||||
* This is deprecated due to ambiguity (y before x), and SHOULD NOT BE USED.
|
||||
*
|
||||
*/
|
||||
scrollTo(
|
||||
y?:
|
||||
| number
|
||||
| {x?: number, y?: number, animated?: boolean, duration?: number},
|
||||
y?: number | {x?: number, y?: number, animated?: boolean},
|
||||
x?: number,
|
||||
animated?: boolean,
|
||||
duration?: number,
|
||||
) {
|
||||
if (typeof y === 'number') {
|
||||
console.warn(
|
||||
@@ -725,13 +716,12 @@ class ScrollView extends React.Component<Props, State> {
|
||||
'animated: true})` instead.',
|
||||
);
|
||||
} else {
|
||||
({x, y, animated, duration} = y || {});
|
||||
({x, y, animated} = y || {});
|
||||
}
|
||||
this._scrollResponder.scrollResponderScrollTo({
|
||||
x: x || 0,
|
||||
y: y || 0,
|
||||
animated: animated !== false,
|
||||
duration: duration,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -741,16 +731,13 @@ class ScrollView extends React.Component<Props, State> {
|
||||
*
|
||||
* Use `scrollToEnd({animated: true})` for smooth animated scrolling,
|
||||
* `scrollToEnd({animated: false})` for immediate scrolling.
|
||||
* For Android, you may specify a duration, e.g. `scrollToEnd({duration: 500})`
|
||||
* for a controlled duration scroll.
|
||||
* If no options are passed, `animated` defaults to true.
|
||||
*/
|
||||
scrollToEnd(options?: {animated?: boolean, duration?: number}) {
|
||||
scrollToEnd(options?: {animated?: boolean}) {
|
||||
// Default to true
|
||||
const animated = (options && options.animated) !== false;
|
||||
this._scrollResponder.scrollResponderScrollToEnd({
|
||||
animated: animated,
|
||||
duration: options && options.duration,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -149,9 +149,7 @@ RCT_EXPORT_METHOD(calculateChildFrames:(nonnull NSNumber *)reactTag
|
||||
RCT_EXPORT_METHOD(scrollTo:(nonnull NSNumber *)reactTag
|
||||
offsetX:(CGFloat)x
|
||||
offsetY:(CGFloat)y
|
||||
animated:(BOOL)animated
|
||||
// TODO(dannycochran) Use the duration here for a ScrollView.
|
||||
duration:(CGFloat __unused)duration)
|
||||
animated:(BOOL)animated)
|
||||
{
|
||||
[self.bridge.uiManager addUIBlock:
|
||||
^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
|
||||
@@ -166,9 +164,7 @@ RCT_EXPORT_METHOD(scrollTo:(nonnull NSNumber *)reactTag
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(scrollToEnd:(nonnull NSNumber *)reactTag
|
||||
animated:(BOOL)animated
|
||||
// TODO(dannycochran) Use the duration here for a ScrollView.
|
||||
duration:(CGFloat __unused)duration)
|
||||
animated:(BOOL)animated)
|
||||
{
|
||||
[self.bridge.uiManager addUIBlock:
|
||||
^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
package com.facebook.react.views.scroll;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
@@ -57,7 +55,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
|
||||
private final Rect mRect = new Rect();
|
||||
|
||||
private boolean mActivelyScrolling;
|
||||
private @Nullable ObjectAnimator mAnimator = null;
|
||||
private @Nullable Rect mClippingRect;
|
||||
private @Nullable String mOverflow = ViewProps.HIDDEN;
|
||||
private boolean mDragging;
|
||||
@@ -186,20 +183,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
|
||||
awakenScrollBars();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for animating to a ScrollView position with a given duration,
|
||||
* instead of using "smoothScrollTo", which does not expose a duration argument.
|
||||
*/
|
||||
public void animateScroll(int mDestX, int mDestY, int mDuration) {
|
||||
if (mAnimator != null) {
|
||||
mAnimator.cancel();
|
||||
}
|
||||
PropertyValuesHolder scrollX = PropertyValuesHolder.ofInt("scrollX", mDestX);
|
||||
PropertyValuesHolder scrollY = PropertyValuesHolder.ofInt("scrollY", mDestY);
|
||||
mAnimator = ObjectAnimator.ofPropertyValuesHolder(this, scrollX, scrollY);
|
||||
mAnimator.setDuration(mDuration).start();
|
||||
}
|
||||
|
||||
public void setOverflow(String overflow) {
|
||||
mOverflow = overflow;
|
||||
invalidate();
|
||||
@@ -283,11 +266,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mAnimator != null) {
|
||||
mAnimator.cancel();
|
||||
mAnimator = null;
|
||||
}
|
||||
|
||||
mVelocityHelper.calculateVelocity(ev);
|
||||
int action = ev.getAction() & MotionEvent.ACTION_MASK;
|
||||
if (action == MotionEvent.ACTION_UP && mDragging) {
|
||||
|
||||
@@ -171,13 +171,8 @@ public class ReactHorizontalScrollViewManager
|
||||
@Override
|
||||
public void scrollTo(
|
||||
ReactHorizontalScrollView scrollView, ReactScrollViewCommandHelper.ScrollToCommandData data) {
|
||||
if (data.mAnimated && data.mDuration != 0) {
|
||||
if (data.mDuration > 0) {
|
||||
// data.mDuration set to -1 to fallbacks to default platform behavior
|
||||
scrollView.animateScroll(data.mDestX, data.mDestY, data.mDuration);
|
||||
} else {
|
||||
scrollView.smoothScrollTo(data.mDestX, data.mDestY);
|
||||
}
|
||||
if (data.mAnimated) {
|
||||
scrollView.smoothScrollTo(data.mDestX, data.mDestY);
|
||||
} else {
|
||||
scrollView.scrollTo(data.mDestX, data.mDestY);
|
||||
}
|
||||
@@ -190,13 +185,8 @@ public class ReactHorizontalScrollViewManager
|
||||
// ScrollView always has one child - the scrollable area
|
||||
int right =
|
||||
scrollView.getChildAt(0).getWidth() + scrollView.getPaddingRight();
|
||||
if (data.mAnimated && data.mDuration != 0) {
|
||||
if (data.mDuration > 0) {
|
||||
// data.mDuration set to -1 to fallbacks to default platform behavior
|
||||
scrollView.animateScroll(right, scrollView.getScrollY(), data.mDuration);
|
||||
} else {
|
||||
scrollView.smoothScrollTo(right, scrollView.getScrollY());
|
||||
}
|
||||
if (data.mAnimated) {
|
||||
scrollView.smoothScrollTo(right, scrollView.getScrollY());
|
||||
} else {
|
||||
scrollView.scrollTo(right, scrollView.getScrollY());
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
package com.facebook.react.views.scroll;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
@@ -55,7 +53,6 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
|
||||
private final VelocityHelper mVelocityHelper = new VelocityHelper();
|
||||
private final Rect mRect = new Rect(); // for reuse to avoid allocation
|
||||
|
||||
private @Nullable ObjectAnimator mAnimator = null;
|
||||
private boolean mActivelyScrolling;
|
||||
private @Nullable Rect mClippingRect;
|
||||
private @Nullable String mOverflow = ViewProps.HIDDEN;
|
||||
@@ -174,20 +171,6 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
|
||||
awakenScrollBars();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for animating to a ScrollView position with a given duration,
|
||||
* instead of using "smoothScrollTo", which does not expose a duration argument.
|
||||
*/
|
||||
public void animateScroll(int mDestX, int mDestY, int mDuration) {
|
||||
if (mAnimator != null) {
|
||||
mAnimator.cancel();
|
||||
}
|
||||
PropertyValuesHolder scrollX = PropertyValuesHolder.ofInt("scrollX", mDestX);
|
||||
PropertyValuesHolder scrollY = PropertyValuesHolder.ofInt("scrollY", mDestY);
|
||||
mAnimator = ObjectAnimator.ofPropertyValuesHolder(this, scrollX, scrollY);
|
||||
mAnimator.setDuration(mDuration).start();
|
||||
}
|
||||
|
||||
public void setOverflow(String overflow) {
|
||||
mOverflow = overflow;
|
||||
invalidate();
|
||||
@@ -272,11 +255,6 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mAnimator != null) {
|
||||
mAnimator.cancel();
|
||||
mAnimator = null;
|
||||
}
|
||||
|
||||
mVelocityHelper.calculateVelocity(ev);
|
||||
int action = ev.getAction() & MotionEvent.ACTION_MASK;
|
||||
if (action == MotionEvent.ACTION_UP && mDragging) {
|
||||
|
||||
@@ -32,25 +32,22 @@ public class ReactScrollViewCommandHelper {
|
||||
|
||||
public static class ScrollToCommandData {
|
||||
|
||||
public final int mDestX, mDestY, mDuration;
|
||||
public final int mDestX, mDestY;
|
||||
public final boolean mAnimated;
|
||||
|
||||
ScrollToCommandData(int destX, int destY, boolean animated, int duration) {
|
||||
ScrollToCommandData(int destX, int destY, boolean animated) {
|
||||
mDestX = destX;
|
||||
mDestY = destY;
|
||||
mAnimated = animated;
|
||||
mDuration = duration;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ScrollToEndCommandData {
|
||||
|
||||
public final int mDuration;
|
||||
public final boolean mAnimated;
|
||||
|
||||
ScrollToEndCommandData(boolean animated, int duration) {
|
||||
ScrollToEndCommandData(boolean animated) {
|
||||
mAnimated = animated;
|
||||
mDuration = duration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,14 +74,12 @@ public class ReactScrollViewCommandHelper {
|
||||
int destX = Math.round(PixelUtil.toPixelFromDIP(args.getDouble(0)));
|
||||
int destY = Math.round(PixelUtil.toPixelFromDIP(args.getDouble(1)));
|
||||
boolean animated = args.getBoolean(2);
|
||||
int duration = (int) Math.round(args.getDouble(3));
|
||||
viewManager.scrollTo(scrollView, new ScrollToCommandData(destX, destY, animated, duration));
|
||||
viewManager.scrollTo(scrollView, new ScrollToCommandData(destX, destY, animated));
|
||||
return;
|
||||
}
|
||||
case COMMAND_SCROLL_TO_END: {
|
||||
boolean animated = args.getBoolean(0);
|
||||
int duration = (int) Math.round(args.getDouble(1));
|
||||
viewManager.scrollToEnd(scrollView, new ScrollToEndCommandData(animated, duration));
|
||||
viewManager.scrollToEnd(scrollView, new ScrollToEndCommandData(animated));
|
||||
return;
|
||||
}
|
||||
case COMMAND_FLASH_SCROLL_INDICATORS:
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
package com.facebook.react.views.scroll;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
|
||||
@@ -191,13 +191,8 @@ public class ReactScrollViewManager
|
||||
@Override
|
||||
public void scrollTo(
|
||||
ReactScrollView scrollView, ReactScrollViewCommandHelper.ScrollToCommandData data) {
|
||||
if (data.mAnimated && data.mDuration != 0) {
|
||||
if (data.mDuration > 0) {
|
||||
// data.mDuration set to -1 to fallbacks to default platform behavior
|
||||
scrollView.animateScroll(data.mDestX, data.mDestY, data.mDuration);
|
||||
} else {
|
||||
scrollView.smoothScrollTo(data.mDestX, data.mDestY);
|
||||
}
|
||||
if (data.mAnimated) {
|
||||
scrollView.smoothScrollTo(data.mDestX, data.mDestY);
|
||||
} else {
|
||||
scrollView.scrollTo(data.mDestX, data.mDestY);
|
||||
}
|
||||
@@ -262,13 +257,8 @@ public class ReactScrollViewManager
|
||||
// ScrollView always has one child - the scrollable area
|
||||
int bottom =
|
||||
scrollView.getChildAt(0).getHeight() + scrollView.getPaddingBottom();
|
||||
if (data.mAnimated && data.mDuration != 0) {
|
||||
if (data.mDuration > 0) {
|
||||
// data.mDuration set to -1 to fallbacks to default platform behavior
|
||||
scrollView.animateScroll(scrollView.getScrollX(), bottom, data.mDuration);
|
||||
} else {
|
||||
scrollView.smoothScrollTo(scrollView.getScrollX(), bottom);
|
||||
}
|
||||
if (data.mAnimated) {
|
||||
scrollView.smoothScrollTo(scrollView.getScrollX(), bottom);
|
||||
} else {
|
||||
scrollView.scrollTo(scrollView.getScrollX(), bottom);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user