原生桥接2(原生View/ViewGroup桥接)
Native层 -View
- 继承 SimpleViewManager
public class CustomBridgeView extends SimpleViewManager<Button> { /** * 桥接 NativeView,需继承自 SimpleViewManager,泛型为NativeView的类型. * 此处仅以 Button 作为范例,展示基本用法. */ /** * 1.指定RN引用时的名称 * "RCTButton": View的引用名称,在RN层声明时,需保持命名一致. */ @Override public String getName() { return "RCTButton"; } /** * 2.在这里根据Context创建NativeView. */ @Override protected Button createViewInstance(ThemedReactContext reactContext) { return new Button(reactContext); } /** * 3.提供给RN层动态配置NativeView的参数,RN层使用时同Props用法. * "name = "textSize"","textSize"作为RN层使用的Prop的名称. */ @ReactProp(name = "textSize") public void setButtonTextSize(Button button, int size) { button.setTextSize(size); } }
- 实现 ReactPackage
public class CustomReactPackage implements ReactPackage { /** * 1.加入供RN层调用库的Module. */ @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Collections.emptyList(); } /** * 2.加入供RN层引用View/ViewGroup的Manager. */ @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { ArrayList<ViewManager> modules = new ArrayList<>(); modules.add(new CustomBridgeView()); return modules; } }
- 实现 ReactApplication
public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override protected String getJSMainModuleName() { return "index"; } @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } /** * 1.加入已声明的ReactPackage * "MainReactPackage()": 默认添加. */ @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new CustomReactPackage() ); } }; @Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); } }
RN层 - TypeScript
- 声明原生View
interface Props { textSize: number style: any } /** * 声明RCTButton的Component,主要是为了显式注入Props. * 这里的Props需要写入已经在NativeViewManager里定义过的ReactProp, * 需要包含style,为了避免ts的类型检查报错,需要说明的是RN里的style对NativeView是生效的. * 默认值可随意写,在引用时传入的值会覆盖这里的默认值. */ class RCTButtonComponent extends Component<Props, {}> { static propTypes: Props = { textSize: , style: null } } /** * 导出已声明的View,这里requireNativeComponent里的第一个参数'RCTButton', * 需要与NativeViewManager里getName()里声明的命名一致。 * requireNativeComponent的包导入来自'react-native'. * "nativeOnly": 一些原生专有的属性,为了不破坏Props的结构并且运行时不报错,添加到此处. */ export const RCTButton = requireNativeComponent('RCTButton', RCTButtonComponent, { nativeOnly: { 'nativeID': true, 'accessibilityComponentType': true, 'onLayout': true, 'testID': true, 'importantForAccessibility': true, 'accessibilityLiveRegion': true, 'accessibilityLabel': true, 'renderToHardwareTextureAndroid': true } } )
- 桥接View组件的引用与RN里的Component引用没有区别。
ViewGroup的桥接
- ViewGroup的桥接与View的桥接的区别:
- ViewGroup需要自定义并继承自ReactViewGroup,并且ViewManager继承自ViewGroupManager,而View可以使用原生View也可以自定义,其ViewManager继承自SimpleViewManager。
- 在RN层引用时,顾名思义,ViewGroup可以作为父容器,而View只能作为子控件。
- 下面贴一段ViewGroup的Native层创建的代码,其他与NativeView一致,不再赘述。
public class CustomBridgeViewGroup extends ViewGroupManager<ReactViewGroup> { /** * 桥接 ViewGroup,需继承自 ViewGroupManager,泛型为ReactViewGroup. * ViewGroup需自定义,并且继承自ReactViewGroup. */ /** * 1.指定RN引用时的名称 * "RCTViewGroup": ViewGroup的引用名称,在RN层声明时,需保持命名一致. */ @Override public String getName() { return "RCTViewGroup"; } /** * 2.在这里根据Context创建自定义ViewGroup. */ @Override protected ReactViewGroup createViewInstance(ThemedReactContext reactContext) { return new CustomViewGroup(reactContext); } /** * 3.自定义继承自ReactViewGroup的ViewGroup. */ private class CustomViewGroup extends ReactViewGroup{ public CustomViewGroup(Context context) { super(context); } } /** * 4.提供给RN层动态配置ViewGroup的参数,RN层使用时同Props用法. * "name = "alpha"","alpha"作为RN层使用的Prop的名称. */ @ReactProp(name = "alpha") public void setAlpha(CustomViewGroup viewGroup, float alpha) { viewGroup.setAlpha(alpha); } }