Skip to content

Commit fc7385c

Browse files
jorge-cabfacebook-github-bot
authored andcommitted
Back out "Fix keyboard navigation for FlatList with removeClippedSubviews enabled"
Summary: Original commit changeset: 1df7f90066df Original Phabricator Diff: D69618406 Original diff caused unintended scrolling on some interactions that trigger focus searching Changelog: [Internal] Reviewed By: Abbondanzo Differential Revision: D71217683 fbshipit-source-id: faa977ba0fddbf776868d6204d283555e169ba96
1 parent bcd6b5f commit fc7385c

File tree

11 files changed

+0
-487
lines changed

11 files changed

+0
-487
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,7 +2396,6 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid
23962396
public fun dispatchCommand (IILcom/facebook/react/bridge/ReadableArray;)V
23972397
public fun dispatchCommand (IILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
23982398
public fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
2399-
public fun findNextFocusableElementMetrics (III)Lcom/facebook/react/fabric/NextFocusableNode;
24002399
public fun getColor (I[Ljava/lang/String;)I
24012400
public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher;
24022401
public fun getPerformanceCounters ()Ljava/util/Map;
@@ -2436,12 +2435,6 @@ public final class com/facebook/react/fabric/FabricUIManagerProviderImpl : com/f
24362435
public fun createUIManager (Lcom/facebook/react/bridge/ReactApplicationContext;)Lcom/facebook/react/bridge/UIManager;
24372436
}
24382437

2439-
public final class com/facebook/react/fabric/NextFocusableNode {
2440-
public fun <init> (IF)V
2441-
public final fun getDeltaScroll ()F
2442-
public final fun getId ()I
2443-
}
2444-
24452438
public class com/facebook/react/fabric/StateWrapperImpl : com/facebook/jni/HybridClassBase, com/facebook/react/uimanager/StateWrapper {
24462439
public fun destroyState ()V
24472440
public fun getStateData ()Lcom/facebook/react/bridge/ReadableNativeMap;
@@ -6204,7 +6197,6 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android
62046197
public fun executeKeyEvent (Landroid/view/KeyEvent;)Z
62056198
public fun flashScrollIndicators ()V
62066199
public fun fling (I)V
6207-
public fun focusSearch (Landroid/view/View;I)Landroid/view/View;
62086200
public fun getChildVisibleRect (Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
62096201
public fun getClippingRect (Landroid/graphics/Rect;)V
62106202
public fun getFlingAnimator ()Landroid/animation/ValueAnimator;
@@ -6327,7 +6319,6 @@ public class com/facebook/react/views/scroll/ReactScrollView : android/widget/Sc
63276319
public fun executeKeyEvent (Landroid/view/KeyEvent;)Z
63286320
public fun flashScrollIndicators ()V
63296321
public fun fling (I)V
6330-
public fun focusSearch (Landroid/view/View;I)Landroid/view/View;
63316322
public fun getChildVisibleRect (Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
63326323
public fun getClippingRect (Landroid/graphics/Rect;)V
63336324
public fun getFlingAnimator ()Landroid/animation/ValueAnimator;
@@ -6448,8 +6439,6 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper {
64486439
public static final fun emitScrollEvent (Landroid/view/ViewGroup;FF)V
64496440
public static final fun emitScrollMomentumBeginEvent (Landroid/view/ViewGroup;II)V
64506441
public static final fun emitScrollMomentumEndEvent (Landroid/view/ViewGroup;)V
6451-
public static final fun findNextClippedElement (Landroid/view/ViewGroup;Landroid/view/View;ILcom/facebook/react/bridge/ReactContext;)Landroid/view/View;
6452-
public static final fun findNextFocusableView (Landroid/view/ViewGroup;Landroid/view/View;IZ)Landroid/view/View;
64536442
public static final fun forceUpdateState (Landroid/view/ViewGroup;)V
64546443
public static final fun getDefaultScrollAnimationDuration (Landroid/content/Context;)I
64556444
public static final fun getNextFlingStartValue (Landroid/view/ViewGroup;III)I
@@ -6459,7 +6448,6 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper {
64596448
public final fun registerFlingAnimator (Landroid/view/ViewGroup;)V
64606449
public static final fun removeLayoutChangeListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$LayoutChangeListener;)V
64616450
public static final fun removeScrollListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ScrollListener;)V
6462-
public static final fun resolveAbsoluteDirection (IZI)I
64636451
public static final fun smoothScrollTo (Landroid/view/ViewGroup;II)V
64646452
public static final fun updateFabricScrollState (Landroid/view/ViewGroup;)V
64656453
public final fun updateFabricScrollState (Landroid/view/ViewGroup;II)V

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import androidx.annotation.NonNull;
3030
import androidx.annotation.Nullable;
3131
import androidx.annotation.UiThread;
32-
import androidx.core.view.ViewCompat.FocusRealDirection;
3332
import com.facebook.common.logging.FLog;
3433
import com.facebook.infer.annotation.ThreadConfined;
3534
import com.facebook.proguard.annotations.DoNotStripAny;
@@ -261,51 +260,6 @@ public <T extends View> int addRootView(final T rootView, final WritableMap init
261260
return rootTag;
262261
}
263262

264-
/**
265-
* Find the next focusable element's id and position relative to the parent from the shadow tree
266-
* based on the current focusable element and the direction.
267-
*
268-
* @return A NextFocusableNode object where the 'id' is the reactId/Tag of the next focusable
269-
* view, and 'deltaScroll' is the scroll delta needed to make the view visible on the screen.
270-
* Returns null if no valid node is found.
271-
*/
272-
public @Nullable NextFocusableNode findNextFocusableElementMetrics(
273-
int parentTag, int focusedTag, @FocusRealDirection int direction) {
274-
if (mBinding == null) {
275-
return null;
276-
}
277-
278-
int generalizedDirection;
279-
280-
switch (direction) {
281-
case View.FOCUS_DOWN:
282-
generalizedDirection = 0;
283-
break;
284-
case View.FOCUS_UP:
285-
generalizedDirection = 1;
286-
break;
287-
case View.FOCUS_RIGHT:
288-
generalizedDirection = 2;
289-
break;
290-
case View.FOCUS_LEFT:
291-
generalizedDirection = 3;
292-
break;
293-
default:
294-
return null;
295-
}
296-
297-
@Nullable
298-
float[] serializedNextFocusableNodeMetrics =
299-
mBinding.findNextFocusableElementMetrics(parentTag, focusedTag, generalizedDirection);
300-
301-
if (serializedNextFocusableNodeMetrics == null) {
302-
return null;
303-
}
304-
305-
return new NextFocusableNode(
306-
(int) serializedNextFocusableNodeMetrics[0], serializedNextFocusableNodeMetrics[1]);
307-
}
308-
309263
@Override
310264
@AnyThread
311265
@ThreadConfined(ANY)

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ internal class FabricUIManagerBinding : HybridClassBase() {
5555
isMountable: Boolean
5656
)
5757

58-
external fun findNextFocusableElementMetrics(
59-
parentTag: Int,
60-
focusedTag: Int,
61-
direction: Int
62-
): FloatArray
63-
6458
external fun stopSurface(surfaceId: Int)
6559

6660
external fun stopSurfaceWithSurfaceHandler(surfaceHandler: SurfaceHandlerBinding)

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/NextFocusableNode.kt

Lines changed: 0 additions & 10 deletions
This file was deleted.

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_DISABLED;
1212
import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_END;
1313
import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_START;
14-
import static com.facebook.react.views.scroll.ReactScrollViewHelper.findNextFocusableView;
1514

1615
import android.animation.ObjectAnimator;
1716
import android.animation.ValueAnimator;
@@ -32,7 +31,6 @@
3231
import android.widget.OverScroller;
3332
import androidx.annotation.Nullable;
3433
import androidx.core.view.ViewCompat;
35-
import androidx.core.view.ViewCompat.FocusRealDirection;
3634
import com.facebook.common.logging.FLog;
3735
import com.facebook.infer.annotation.Assertions;
3836
import com.facebook.infer.annotation.Nullsafe;
@@ -774,17 +772,6 @@ protected void onDetachedFromWindow() {
774772
}
775773
}
776774

777-
@Override
778-
public @Nullable View focusSearch(View focused, @FocusRealDirection int direction) {
779-
@Nullable View nextfocusableView = findNextFocusableView(this, focused, direction, true);
780-
781-
if (nextfocusableView != null) {
782-
return nextfocusableView;
783-
}
784-
785-
return super.focusSearch(focused, direction);
786-
}
787-
788775
@Override
789776
public void updateClippingRect() {
790777
if (!mRemoveClippedSubviews) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_DISABLED;
1212
import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_END;
1313
import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_START;
14-
import static com.facebook.react.views.scroll.ReactScrollViewHelper.findNextFocusableView;
1514

1615
import android.animation.ObjectAnimator;
1716
import android.animation.ValueAnimator;
@@ -32,7 +31,6 @@
3231
import androidx.annotation.NonNull;
3332
import androidx.annotation.Nullable;
3433
import androidx.core.view.ViewCompat;
35-
import androidx.core.view.ViewCompat.FocusRealDirection;
3634
import com.facebook.common.logging.FLog;
3735
import com.facebook.infer.annotation.Assertions;
3836
import com.facebook.infer.annotation.Nullsafe;
@@ -361,18 +359,6 @@ protected void onDetachedFromWindow() {
361359
}
362360
}
363361

364-
@Override
365-
public @Nullable View focusSearch(View focused, @FocusRealDirection int direction) {
366-
367-
@Nullable View nextfocusableView = findNextFocusableView(this, focused, direction, false);
368-
369-
if (nextfocusableView != null) {
370-
return nextfocusableView;
371-
}
372-
373-
return super.focusSearch(focused, direction);
374-
}
375-
376362
/**
377363
* Since ReactScrollView handles layout changes on JS side, it does not call super.onlayout due to
378364
* which mIsLayoutDirty flag in ScrollView remains true and prevents scrolling to child when

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,15 @@ import android.animation.Animator
1111
import android.animation.ValueAnimator
1212
import android.content.Context
1313
import android.graphics.Point
14-
import android.view.FocusFinder
1514
import android.view.View
1615
import android.view.ViewGroup
1716
import android.widget.OverScroller
18-
import androidx.core.view.ViewCompat.FocusRealDirection
1917
import com.facebook.common.logging.FLog
2018
import com.facebook.react.bridge.ReactContext
2119
import com.facebook.react.bridge.WritableMap
2220
import com.facebook.react.bridge.WritableNativeMap
2321
import com.facebook.react.common.ReactConstants
24-
import com.facebook.react.fabric.FabricUIManager
2522
import com.facebook.react.uimanager.PixelUtil.toDIPFromPixel
26-
import com.facebook.react.uimanager.PixelUtil.toPixelFromDIP
2723
import com.facebook.react.uimanager.StateWrapper
2824
import com.facebook.react.uimanager.UIManagerHelper
2925
import com.facebook.react.uimanager.common.UIManagerType
@@ -466,89 +462,6 @@ public object ReactScrollViewHelper {
466462
return Point(scroller.finalX, scroller.finalY)
467463
}
468464

469-
@JvmStatic
470-
public fun findNextFocusableView(
471-
host: ViewGroup,
472-
focused: View,
473-
@FocusRealDirection direction: Int,
474-
horizontal: Boolean
475-
): View? {
476-
val absDir = resolveAbsoluteDirection(direction, horizontal, host.getLayoutDirection())
477-
478-
/*
479-
* Check if we can focus the next element in the absolute direction within the ScrollView,
480-
* if we can't, look into the shadow tree to find the next focusable element
481-
*/
482-
val ff = FocusFinder.getInstance()
483-
val result = ff.findNextFocus(host, focused, absDir)
484-
485-
if (result != null) {
486-
return result
487-
}
488-
489-
/*
490-
* Attempt to focus the next focusable but clipped element on the list if there is one, since
491-
* the view is clipped it is not currently in the hierarchy so we scroll it into view and then
492-
* focus it.
493-
*/
494-
return findNextClippedElement(host, focused, absDir, host.context as ReactContext)
495-
}
496-
497-
/**
498-
* Attempts to focus the next element in the specified direction within the scrollView.
499-
*
500-
* @return true if a new element was successfully focused, otherwise false.
501-
*/
502-
@JvmStatic
503-
public fun findNextClippedElement(
504-
scrollView: ViewGroup,
505-
focused: View,
506-
@FocusRealDirection direction: Int,
507-
context: ReactContext,
508-
): View? {
509-
val uimanager = UIManagerHelper.getUIManager(context, UIManagerType.FABRIC) ?: return null
510-
511-
val nextFocusableViewMetrics =
512-
(uimanager as FabricUIManager).findNextFocusableElementMetrics(
513-
scrollView.id, focused.id, direction)
514-
515-
if (nextFocusableViewMetrics != null) {
516-
517-
when (direction) {
518-
View.FOCUS_UP,
519-
View.FOCUS_DOWN -> {
520-
scrollView.scrollBy(0, toPixelFromDIP(nextFocusableViewMetrics.deltaScroll).toInt())
521-
}
522-
View.FOCUS_RIGHT,
523-
View.FOCUS_LEFT -> {
524-
scrollView.scrollBy(toPixelFromDIP(nextFocusableViewMetrics.deltaScroll).toInt(), 0)
525-
}
526-
else -> return null
527-
}
528-
return scrollView.findViewById(nextFocusableViewMetrics.id)
529-
}
530-
return null
531-
}
532-
533-
@JvmStatic
534-
public fun resolveAbsoluteDirection(
535-
@FocusRealDirection direction: Int,
536-
horizontal: Boolean,
537-
layoutDirection: Int
538-
): Int {
539-
val rtl: Boolean = layoutDirection == View.LAYOUT_DIRECTION_RTL
540-
541-
return if (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD) {
542-
if (horizontal) {
543-
if ((direction == View.FOCUS_FORWARD) != rtl) View.FOCUS_RIGHT else View.FOCUS_LEFT
544-
} else {
545-
if (direction == View.FOCUS_FORWARD) View.FOCUS_DOWN else View.FOCUS_UP
546-
}
547-
} else {
548-
direction
549-
}
550-
}
551-
552465
public interface ScrollListener {
553466
public fun onScroll(
554467
scrollView: ViewGroup?,

0 commit comments

Comments
 (0)