diff --git a/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK b/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK
index 66f78ea103f..8c538aa0e96 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK
+++ b/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK
@@ -64,7 +64,6 @@ rn_android_library(
react_native_target("java/com/facebook/react/views/text/frescosupport:frescosupport"),
react_native_target("java/com/facebook/react/views/textinput:textinput"),
react_native_target("java/com/facebook/react/views/view:view"),
- react_native_target("java/com/facebook/react/views/viewpager:viewpager"),
react_native_target("java/com/facebook/react/module/annotations:annotations"),
react_native_target("res:shell"),
],
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/BUCK
deleted file mode 100644
index 9784b3051f2..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/BUCK
+++ /dev/null
@@ -1,31 +0,0 @@
-load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_target", "rn_android_library")
-
-rn_android_library(
- name = "viewpager",
- srcs = glob(["**/*.java"]),
- is_androidx = True,
- labels = ["supermodule:xplat/default/public.react_native.infra"],
- provided_deps = [
- react_native_dep("third-party/android/androidx:annotation"),
- react_native_dep("third-party/android/androidx:core"),
- react_native_dep("third-party/android/androidx:fragment"),
- react_native_dep("third-party/android/androidx:legacy-support-core-ui"),
- react_native_dep("third-party/android/androidx:legacy-support-core-utils"),
- ],
- required_for_source_only_abi = True,
- visibility = [
- "PUBLIC",
- ],
- deps = [
- react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"),
- react_native_dep("third-party/java/infer-annotations:infer-annotations"),
- react_native_dep("third-party/java/jsr-305:jsr-305"),
- react_native_target("java/com/facebook/react/bridge:bridge"),
- react_native_target("java/com/facebook/react/common:common"),
- react_native_target("java/com/facebook/react/module/annotations:annotations"),
- react_native_target("java/com/facebook/react/uimanager:uimanager"),
- react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
- react_native_target("java/com/facebook/react/views/scroll:scroll"),
- react_native_target("java/com/facebook/react/viewmanagers:viewmanagers"),
- ],
-)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageScrollEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageScrollEvent.java
deleted file mode 100644
index 2fcc64de002..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageScrollEvent.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.
- */
-
-package com.facebook.react.views.viewpager;
-
-import com.facebook.react.bridge.Arguments;
-import com.facebook.react.bridge.WritableMap;
-import com.facebook.react.uimanager.events.Event;
-import com.facebook.react.uimanager.events.RCTEventEmitter;
-
-/**
- * Event emitted by {@link ReactViewPager} when user scrolls between pages (or when animating
- * between pages).
- *
- *
Additional data provided by this event:
- *
- *
- * - position - index of first page from the left that is currently visible
- *
- offset - value from range [0,1) describing stage between page transitions. Value x means
- * that (1 - x) fraction of the page at "position" index is visible, and x fraction of the
- * next page is visible.
- *
- */
-/* package */ class PageScrollEvent extends Event {
-
- public static final String EVENT_NAME = "topPageScroll";
-
- private final int mPosition;
- private final float mOffset;
-
- protected PageScrollEvent(int viewTag, int position, float offset) {
- super(viewTag);
- mPosition = position;
-
- // folly::toJson default options don't support serialize NaN or Infinite value
- mOffset = (Float.isInfinite(offset) || Float.isNaN(offset)) ? 0.0f : offset;
- }
-
- @Override
- public String getEventName() {
- return EVENT_NAME;
- }
-
- @Override
- public void dispatch(RCTEventEmitter rctEventEmitter) {
- rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
- }
-
- private WritableMap serializeEventData() {
- WritableMap eventData = Arguments.createMap();
- eventData.putInt("position", mPosition);
- eventData.putDouble("offset", mOffset);
- return eventData;
- }
-}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageScrollStateChangedEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageScrollStateChangedEvent.java
deleted file mode 100644
index 68585a75ca5..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageScrollStateChangedEvent.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- */
-
-package com.facebook.react.views.viewpager;
-
-import com.facebook.react.bridge.Arguments;
-import com.facebook.react.bridge.WritableMap;
-import com.facebook.react.uimanager.events.Event;
-import com.facebook.react.uimanager.events.RCTEventEmitter;
-
-/**
- * Event emitted by {@link ReactViewPager} when user scrolling state changed.
- *
- * Additional data provided by this event:
- *
- *
- * - pageScrollState - {Idle,Dragging,Settling}
- *
- */
-class PageScrollStateChangedEvent extends Event {
-
- public static final String EVENT_NAME = "topPageScrollStateChanged";
-
- private final String mPageScrollState;
-
- protected PageScrollStateChangedEvent(int viewTag, String pageScrollState) {
- super(viewTag);
- mPageScrollState = pageScrollState;
- }
-
- @Override
- public String getEventName() {
- return EVENT_NAME;
- }
-
- @Override
- public void dispatch(RCTEventEmitter rctEventEmitter) {
- rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
- }
-
- private WritableMap serializeEventData() {
- WritableMap eventData = Arguments.createMap();
- eventData.putString("pageScrollState", mPageScrollState);
- return eventData;
- }
-}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageSelectedEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageSelectedEvent.java
deleted file mode 100644
index 8d59e887cb6..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/PageSelectedEvent.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- */
-
-package com.facebook.react.views.viewpager;
-
-import com.facebook.react.bridge.Arguments;
-import com.facebook.react.bridge.WritableMap;
-import com.facebook.react.uimanager.events.Event;
-import com.facebook.react.uimanager.events.RCTEventEmitter;
-
-/**
- * Event emitted by {@link ReactViewPager} when selected page changes.
- *
- * Additional data provided by this event:
- *
- *
- * - position - index of page that has been selected
- *
- */
-/* package */ class PageSelectedEvent extends Event {
-
- public static final String EVENT_NAME = "topPageSelected";
-
- private final int mPosition;
-
- protected PageSelectedEvent(int viewTag, int position) {
- super(viewTag);
- mPosition = position;
- }
-
- @Override
- public String getEventName() {
- return EVENT_NAME;
- }
-
- @Override
- public void dispatch(RCTEventEmitter rctEventEmitter) {
- rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
- }
-
- private WritableMap serializeEventData() {
- WritableMap eventData = Arguments.createMap();
- eventData.putInt("position", mPosition);
- return eventData;
- }
-}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java
deleted file mode 100644
index 398751a8f6e..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * 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.
- */
-
-package com.facebook.react.views.viewpager;
-
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import androidx.viewpager.widget.PagerAdapter;
-import androidx.viewpager.widget.ViewPager;
-import com.facebook.common.logging.FLog;
-import com.facebook.infer.annotation.Assertions;
-import com.facebook.react.bridge.ReactContext;
-import com.facebook.react.common.ReactConstants;
-import com.facebook.react.uimanager.UIManagerModule;
-import com.facebook.react.uimanager.events.EventDispatcher;
-import com.facebook.react.uimanager.events.NativeGestureUtil;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Wrapper view for {@link ViewPager}. It's forwarding calls to {@link ViewGroup#addView} to add
- * views to custom {@link PagerAdapter} instance which is used by {@link NativeViewHierarchyManager}
- * to add children nodes according to react views hierarchy.
- */
-public class ReactViewPager extends ViewPager {
-
- private class Adapter extends PagerAdapter {
-
- private final List mViews = new ArrayList<>();
- private boolean mIsViewPagerInIntentionallyInconsistentState = false;
-
- void addView(View child, int index) {
- mViews.add(index, child);
- notifyDataSetChanged();
- // This will prevent view pager from detaching views for pages that are not currently selected
- // We need to do that since {@link ViewPager} relies on layout passes to position those views
- // in a right way (also thanks to {@link ReactViewPagerManager#needsCustomLayoutForChildren}
- // returning {@code true}). Currently we only call {@link View#measure} and
- // {@link View#layout} after yoga step.
-
- // TODO(7323049): Remove this workaround once we figure out a way to re-layout some views on
- // request
- setOffscreenPageLimit(mViews.size());
- }
-
- void removeViewAt(int index) {
- mViews.remove(index);
- notifyDataSetChanged();
-
- // TODO(7323049): Remove this workaround once we figure out a way to re-layout some views on
- // request
- setOffscreenPageLimit(mViews.size());
- }
-
- /** Replace a set of views to the ViewPager adapter and update the ViewPager */
- void setViews(List views) {
- mViews.clear();
- mViews.addAll(views);
- notifyDataSetChanged();
-
- // we want to make sure we return POSITION_NONE for every view here, since this is only
- // called after a removeAllViewsFromAdapter
- mIsViewPagerInIntentionallyInconsistentState = false;
- }
-
- /**
- * Remove all the views from the adapter and de-parents them from the ViewPager After calling
- * this, it is expected that notifyDataSetChanged should be called soon afterwards.
- */
- void removeAllViewsFromAdapter(ViewPager pager) {
- mViews.clear();
- pager.removeAllViews();
- // set this, so that when the next addViews is called, we return POSITION_NONE for every
- // entry so we can remove whichever views we need to and add the ones that we need to.
- mIsViewPagerInIntentionallyInconsistentState = true;
- }
-
- View getViewAt(int index) {
- return mViews.get(index);
- }
-
- @Override
- public int getCount() {
- return mViews.size();
- }
-
- @Override
- public int getItemPosition(Object object) {
- // if we've removed all views, we want to return POSITION_NONE intentionally
- return mIsViewPagerInIntentionallyInconsistentState || !mViews.contains(object)
- ? POSITION_NONE
- : mViews.indexOf(object);
- }
-
- @Override
- public Object instantiateItem(ViewGroup container, int position) {
- View view = mViews.get(position);
- container.addView(view, 0, generateDefaultLayoutParams());
- return view;
- }
-
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView((View) object);
- }
-
- @Override
- public boolean isViewFromObject(View view, Object object) {
- return view == object;
- }
- }
-
- private class PageChangeListener implements ViewPager.OnPageChangeListener {
-
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- mEventDispatcher.dispatchEvent(new PageScrollEvent(getId(), position, positionOffset));
- }
-
- @Override
- public void onPageSelected(int position) {
- if (!mIsCurrentItemFromJs) {
- mEventDispatcher.dispatchEvent(new PageSelectedEvent(getId(), position));
- }
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
- String pageScrollState;
- switch (state) {
- case SCROLL_STATE_IDLE:
- pageScrollState = "idle";
- break;
- case SCROLL_STATE_DRAGGING:
- pageScrollState = "dragging";
- break;
- case SCROLL_STATE_SETTLING:
- pageScrollState = "settling";
- break;
- default:
- throw new IllegalStateException("Unsupported pageScrollState");
- }
- mEventDispatcher.dispatchEvent(new PageScrollStateChangedEvent(getId(), pageScrollState));
- }
- }
-
- private final EventDispatcher mEventDispatcher;
- private boolean mIsCurrentItemFromJs;
- private boolean mScrollEnabled = true;
-
- public ReactViewPager(ReactContext reactContext) {
- super(reactContext);
- mEventDispatcher =
- Assertions.assertNotNull(reactContext.getNativeModule(UIManagerModule.class))
- .getEventDispatcher();
- mIsCurrentItemFromJs = false;
- setOnPageChangeListener(new PageChangeListener());
- setAdapter(new Adapter());
- }
-
- @Override
- public Adapter getAdapter() {
- return (Adapter) super.getAdapter();
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (!mScrollEnabled) {
- return false;
- }
-
- try {
- if (super.onInterceptTouchEvent(ev)) {
- NativeGestureUtil.notifyNativeGestureStarted(this, ev);
- return true;
- }
- } catch (IllegalArgumentException e) {
- // Log and ignore the error. This seems to be a bug in the android SDK and
- // this is the commonly accepted workaround.
- // https://tinyurl.com/mw6qkod (Stack Overflow)
- FLog.w(ReactConstants.TAG, "Error intercepting touch event.", e);
- }
-
- return false;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (!mScrollEnabled) {
- return false;
- }
-
- try {
- return super.onTouchEvent(ev);
- } catch (IllegalArgumentException e) {
- // Log and ignore the error. This seems to be a bug in the android SDK and
- // this is the commonly accepted workaround.
- // https://fburl.com/5d3iw7d9
- FLog.w(ReactConstants.TAG, "Error handling touch event.", e);
- }
-
- return false;
- }
-
- public void setCurrentItemFromJs(int item, boolean animated) {
- mIsCurrentItemFromJs = true;
- setCurrentItem(item, animated);
- mIsCurrentItemFromJs = false;
- }
-
- public void setScrollEnabled(boolean scrollEnabled) {
- mScrollEnabled = scrollEnabled;
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- // The viewpager reset an internal flag on this method so we need to run another layout pass
- // after attaching to window.
- this.requestLayout();
- post(measureAndLayout);
- }
-
- private final Runnable measureAndLayout =
- new Runnable() {
- @Override
- public void run() {
- measure(
- MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
- layout(getLeft(), getTop(), getRight(), getBottom());
- }
- };
-
- /*package*/ void addViewToAdapter(View child, int index) {
- getAdapter().addView(child, index);
- }
-
- /*package*/ void removeViewFromAdapter(int index) {
- getAdapter().removeViewAt(index);
- }
-
- /*package*/ int getViewCountInAdapter() {
- return getAdapter().getCount();
- }
-
- /*package*/ View getViewFromAdapter(int index) {
- return getAdapter().getViewAt(index);
- }
-
- public void setViews(List views) {
- getAdapter().setViews(views);
- }
-
- public void removeAllViewsFromAdapter() {
- getAdapter().removeAllViewsFromAdapter(this);
- }
-}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPagerManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPagerManager.java
deleted file mode 100644
index bf6af60998b..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPagerManager.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.
- */
-
-package com.facebook.react.views.viewpager;
-
-import android.view.View;
-import androidx.annotation.Nullable;
-import com.facebook.infer.annotation.Assertions;
-import com.facebook.react.bridge.ReadableArray;
-import com.facebook.react.common.MapBuilder;
-import com.facebook.react.module.annotations.ReactModule;
-import com.facebook.react.uimanager.PixelUtil;
-import com.facebook.react.uimanager.ThemedReactContext;
-import com.facebook.react.uimanager.ViewGroupManager;
-import com.facebook.react.uimanager.ViewManagerDelegate;
-import com.facebook.react.uimanager.annotations.ReactProp;
-import com.facebook.react.viewmanagers.AndroidViewPagerManagerDelegate;
-import com.facebook.react.viewmanagers.AndroidViewPagerManagerInterface;
-import java.util.Map;
-
-/** Instance of {@link ViewManager} that provides native {@link ViewPager} view. */
-@ReactModule(name = ReactViewPagerManager.REACT_CLASS)
-public class ReactViewPagerManager extends ViewGroupManager
- implements AndroidViewPagerManagerInterface {
-
- public static final String REACT_CLASS = "AndroidViewPager";
-
- public static final int COMMAND_SET_PAGE = 1;
- public static final int COMMAND_SET_PAGE_WITHOUT_ANIMATION = 2;
-
- private final ViewManagerDelegate mDelegate;
-
- public ReactViewPagerManager() {
- mDelegate = new AndroidViewPagerManagerDelegate<>(this);
- }
-
- @Override
- public String getName() {
- return REACT_CLASS;
- }
-
- @Override
- protected ReactViewPager createViewInstance(ThemedReactContext reactContext) {
- return new ReactViewPager(reactContext);
- }
-
- @Override
- @ReactProp(name = "scrollEnabled", defaultBoolean = true)
- public void setScrollEnabled(ReactViewPager viewPager, boolean value) {
- viewPager.setScrollEnabled(value);
- }
-
- @Override
- public boolean needsCustomLayoutForChildren() {
- return true;
- }
-
- @Override
- public Map getExportedCustomDirectEventTypeConstants() {
- return MapBuilder.of(
- PageScrollEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPageScroll"),
- PageScrollStateChangedEvent.EVENT_NAME,
- MapBuilder.of("registrationName", "onPageScrollStateChanged"),
- PageSelectedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPageSelected"));
- }
-
- @Override
- public Map getCommandsMap() {
- return MapBuilder.of(
- "setPage", COMMAND_SET_PAGE, "setPageWithoutAnimation", COMMAND_SET_PAGE_WITHOUT_ANIMATION);
- }
-
- @Override
- public void receiveCommand(
- ReactViewPager viewPager, int commandType, @Nullable ReadableArray args) {
- Assertions.assertNotNull(viewPager);
- Assertions.assertNotNull(args);
- switch (commandType) {
- case COMMAND_SET_PAGE:
- {
- viewPager.setCurrentItemFromJs(args.getInt(0), true);
- return;
- }
- case COMMAND_SET_PAGE_WITHOUT_ANIMATION:
- {
- viewPager.setCurrentItemFromJs(args.getInt(0), false);
- return;
- }
- default:
- throw new IllegalArgumentException(
- String.format(
- "Unsupported command %d received by %s.", commandType, getClass().getSimpleName()));
- }
- }
-
- @Override
- public void receiveCommand(
- ReactViewPager viewPager, String commandType, @Nullable ReadableArray args) {
- Assertions.assertNotNull(viewPager);
- Assertions.assertNotNull(args);
- switch (commandType) {
- case "setPage":
- {
- viewPager.setCurrentItemFromJs(args.getInt(0), true);
- return;
- }
- case "setPageWithoutAnimation":
- {
- viewPager.setCurrentItemFromJs(args.getInt(0), false);
- return;
- }
- default:
- throw new IllegalArgumentException(
- String.format(
- "Unsupported command %d received by %s.", commandType, getClass().getSimpleName()));
- }
- }
-
- @Override
- public void addView(ReactViewPager parent, View child, int index) {
- parent.addViewToAdapter(child, index);
- }
-
- @Override
- public int getChildCount(ReactViewPager parent) {
- return parent.getViewCountInAdapter();
- }
-
- @Override
- public View getChildAt(ReactViewPager parent, int index) {
- return parent.getViewFromAdapter(index);
- }
-
- @Override
- public void removeViewAt(ReactViewPager parent, int index) {
- parent.removeViewFromAdapter(index);
- }
-
- @Override
- @ReactProp(name = "pageMargin", defaultInt = 0)
- public void setPageMargin(ReactViewPager pager, int margin) {
- pager.setPageMargin((int) PixelUtil.toPixelFromDIP(margin));
- }
-
- @Override
- @ReactProp(name = "peekEnabled", defaultBoolean = false)
- public void setPeekEnabled(ReactViewPager pager, boolean peekEnabled) {
- pager.setClipToPadding(!peekEnabled);
- }
-
- @Override
- public void setInitialPage(ReactViewPager view, int value) {}
-
- @Override
- public void setKeyboardDismissMode(ReactViewPager view, @Nullable String value) {}
-
- @Override
- public void setPage(ReactViewPager view, int page) {
- view.setCurrentItemFromJs(page, true);
- }
-
- @Override
- public void setPageWithoutAnimation(ReactViewPager view, int page) {
- view.setCurrentItemFromJs(page, false);
- }
-
- @Override
- public ViewManagerDelegate getDelegate() {
- return mDelegate;
- }
-}