React Native view Tagで原生のViewを取得します.

2583 ワード

原文:http://blog.fiftykg.com/font_end/react_native/React Native-view Tagを通じて原生のViewを取得する.
前言
前端の学生はreactTagをAndroidの原生に伝えたいです.元の学生に対応するViewを見つけて、黒科学技術の操作をしてください.
そして問題がありました.React NativeのreactTagは一つのint値ですが、Activity#findViewByIdidとは同じものではありません.
分析
1、React NativeがAndroidの元に提供する操作UIのModuleはUICManager Moduleであり、コードはviewTagを検索して、view Tagを通じてviewを操作するロジックがmUImplementationにあることを示しています.
@ReactMethod
public void removeRootView(int rootViewTag) {
mUIImplementation.removeRootView(rootViewTag);
}

public void updateNodeSize(int nodeViewTag, int newWidth, int newHeight) {
getReactApplicationContext().assertOnNativeModulesQueueThread();

mUIImplementation.updateNodeSize(nodeViewTag, newWidth, newHeight);
}
2、UImplementationを見て、viewTagを検索して、操作のロジックはmShadowNodeRegistrymReactShadowNodeにあり、ShadowNodeRegistryはReact ShadowNodeとの論理であるので、React ShadowNodeを見続けます.検索してみると、怪しいタイプのNativeViewhierarchyManagerが発見できます.カテゴリのコメントを見て、NativeViewerhyManagerは原生ViewとReact Native View Managerのマッピング関係を処理しました.方法を見て、reolveViewが入るのは1つの(で、帰るのは1つのViewで、これであるべきです!最終テストでもそうだった.あとは操作次第!
操作
はい、反射です.
public static View getViewByTag(ReactContext reactContext, int viewTag) {
NativeViewHierarchyManager manager = getNativeViewHierarchyManager(reactContext);
if (manager == null) {
return null;
}
return manager.resolveView(viewTag);
}

public static NativeViewHierarchyManager getNativeViewHierarchyManager(
ReactContext reactContext) {
try {
//    UIImplementation
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
UIImplementation uiImplementation = uiManager.getUIImplementation();
//    UIImplementation#mOperationsQueue
Field mOperationsQueueField = uiImplementation.getClass()
.getDeclaredField("mOperationsQueue");
mOperationsQueueField.setAccessible(true);
UIViewOperationQueue uiViewOperationQueue = (UIViewOperationQueue) mOperationsQueueField
.get(uiImplementation);
//    UIViewOperationQueue#NativeViewHierarchyManager
Field mNativeViewHierarchyManagerField = UIViewOperationQueue.class
.getDeclaredField("mNativeViewHierarchyManager");
mNativeViewHierarchyManagerField.setAccessible(true);
NativeViewHierarchyManager mNativeViewHierarchyManager = (NativeViewHierarchyManager) mNativeViewHierarchyManagerField
.get(uiViewOperationQueue);
return mNativeViewHierarchyManager;
} catch (NoSuchFieldException e) {
e.printStackTrace();
return null;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}