mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add fabric implementation to find Top-Most relative and relevant parent of a child view (#50825)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50825 Pull Request resolved: https://github.com/facebook/react-native/pull/50404 Add another function to fabric to get the topmost stacking context parent given a root and a child. This is to be used on focus searching algorithm in the case where the next focusable child is deeper in the hierarchy meaning we need to find the top most parent in the Android hierarchy and lay that out as well before transferring focus. If we don't lay out the parent as well as the next focusable view: - The next focusable view might lack context given by the parent - If the parent is a scrollview and has removeClippedSubviews enabled then laying out the next focusable view will not work - If the view is deeper in the android hierarchy in some cases it won't be layed out unless the parent is Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D73114933 fbshipit-source-id: 081720199943eff78966982a5fd1c921d4e105fd
This commit is contained in:
committed by
Facebook GitHub Bot
parent
c31699b760
commit
98c10d568e
+2
@@ -57,6 +57,8 @@ internal class FabricUIManagerBinding : HybridClassBase() {
|
||||
|
||||
external fun findNextFocusableElement(parentTag: Int, focusedTag: Int, direction: Int): Int
|
||||
|
||||
external fun findRelativeTopMostParent(rootTag: Int, childTag: Int): Int
|
||||
|
||||
external fun stopSurface(surfaceId: Int)
|
||||
|
||||
external fun stopSurfaceWithSurfaceHandler(surfaceHandler: SurfaceHandlerBinding)
|
||||
|
||||
+37
@@ -253,6 +253,40 @@ jint FabricUIManagerBinding::findNextFocusableElement(
|
||||
return nextNode->getTag();
|
||||
}
|
||||
|
||||
jint FabricUIManagerBinding::findRelativeTopMostParent(
|
||||
jint rootTag,
|
||||
jint childTag) {
|
||||
std::shared_ptr<UIManager> uimanager = getScheduler()->getUIManager();
|
||||
|
||||
ShadowNode::Shared childShadowNode =
|
||||
uimanager->findShadowNodeByTag_DEPRECATED(childTag);
|
||||
ShadowNode::Shared rootShadowNode =
|
||||
uimanager->findShadowNodeByTag_DEPRECATED(rootTag);
|
||||
|
||||
if (childShadowNode == nullptr || rootShadowNode == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ShadowNode::AncestorList ancestorList =
|
||||
childShadowNode->getFamily().getAncestors(*rootShadowNode);
|
||||
|
||||
if (ancestorList.empty() || ancestorList.size() < 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ignore the first ancestor as it is the rootShadowNode itself
|
||||
for (auto it = std::next(ancestorList.begin()); it != ancestorList.end();
|
||||
++it) {
|
||||
auto& ancestor = *it;
|
||||
if (ancestor.first.get().getTraits().check(
|
||||
ShadowNodeTraits::Trait::FormsStackingContext)) {
|
||||
return ancestor.first.get().getTag();
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Used by non-bridgeless+Fabric
|
||||
void FabricUIManagerBinding::startSurfaceWithConstraints(
|
||||
jint surfaceId,
|
||||
@@ -728,6 +762,9 @@ void FabricUIManagerBinding::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"findNextFocusableElement",
|
||||
FabricUIManagerBinding::findNextFocusableElement),
|
||||
makeNativeMethod(
|
||||
"findRelativeTopMostParent",
|
||||
FabricUIManagerBinding::findRelativeTopMostParent),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -135,6 +135,8 @@ class FabricUIManagerBinding : public jni::HybridClass<FabricUIManagerBinding>,
|
||||
jint
|
||||
findNextFocusableElement(jint parentTag, jint focusedTag, jint direction);
|
||||
|
||||
jint findRelativeTopMostParent(jint rootTag, jint childTag);
|
||||
|
||||
void uninstallFabricUIManager();
|
||||
|
||||
// Private member variables
|
||||
|
||||
Reference in New Issue
Block a user