原生橋接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); } }