React Native 在 Native Modules 方面非常强大。您并不仅限于使用 JavaScript。但是,本机模块的文档并不是那么好。你需要自己挖掘一些功能。ViewGroupManager 就是其中之一。
我将假设您熟悉 Native Modules 并且至少使用过一个 Native Modules 开发过 SimpleViewManager
https://facebook.github.io/react-native/docs/native-components-android
View是很好的占位符,但它们不能包含其他View。假设您有这个最简单的 Native View。
public class NativeView extends SimpleViewManager<View> {
public static final String REACT_CLASS = "NativeView";
@Override
public String getName() {
return REACT_CLASS;
}
@Override
public View createViewInstance(ThemedReactContext context) {
View v = new View(context);
v.setBackgroundColor(Color.RED);
return v;
}
}
并使用 JS 调用它
const NativeView = requireNativeComponent('NativeView')
...
<NativeView style={{ height: 100, width: 100 }} />
您将看到一个红色背景的方形 (100x100) 视图。这是我们使用代码所期望的。但是如果你把JS代码改成下面这样:
<NativeView style={{height: 100, width: 100}}>
<Text>I am a text view inside a native view</Text>
</NativeView>
你会得到一个错误:
android.view.View cannot be cast to android.view.ViewGroup
这是因为我们试图在视图中添加一个文本视图。NativeView 对象是一个简单的 Android View 对象。它不能持有另一种View。只有 ViewGroup 可以持有其他视图。如果您想与视图建立父子关系,则需要使用布局。像 LinearLayout 或 RelativeLayout 等布局类是 ViewGroup 的子类。
因此SimpleViewManager
public class NativeLinearLayout extends LinearLayout {
public NativeLinearLayout(Context context) {
super(context);
}
}
并从我们用于扩展 SimpleViewManager 的主类中调用它:
public class NativeView extends ViewGroupManager<NativeLinearLayout> {
public static final String REACT_CLASS = "NativeView";
@Override
public String getName() {
return REACT_CLASS;
}
@Override
public NativeLinearLayout createViewInstance(ThemedReactContext context) {
NativeLinearLayout nativeLinearLayout = new NativeLinearLayout(context);
return nativeLinearLayout;
}
}
这将起作用并将从 JS 创建的 Text 对象插入到 NativeLinearLayout 对象中。
我们还可以从原生布局内部创建另一个 TextView 并将它们组合在一起:
但是现在因为你处理的视图有点低级(low level),React Native 或 CSS 不会帮助样式或布局。您需要使用 setLayoutParams 等本机命令自行处理。
iOS 等效于 View 是 UIView,它们可以保存子视图。因此,在 iOS 中您不需要其他解决方案。本机 UI 组件文档的默认配置将正常工作。
https://cuneyt.aliustaoglu.biz/en/advanced-react-native-viewgroupmanager-android/