ImageView 的例子
在这个例子里,我们来看看为了让 JavaScript 中可以使用 ImageView,需要做哪些准备工作。
原生视图需要被一个ViewManager
的派生类(或者更常见的,SimpleViewManager
的派生类)创建和管理。一个SimpleViewManager
可以用于这个场景,是因为它能够包含更多公共的属性,譬如背景颜色、透明度、Flexbox 布局等等。
NativeViewHierarchyManager
,NativeViewHierarchyManager 则会反过来委托它们在需要的时候去设置和更新视图的属性。ViewManager
还会代理视图的所有委托,并给 JavaScript 发回对应的事件。提供原生视图很简单:
- 创建一个 ViewManager 的子类。
- 实现
createViewInstance
方法。 - 导出视图的属性设置器:使用
@ReactProp
(或@ReactPropGroup
)注解。 - 把这个视图管理类注册到应用程序包的
createViewManagers
里。 - 实现 JavaScript 模块。
... public class ReactImageManager extends SimpleViewManager<ReactImageView> { public static final String REACT_CLASS = "RCTImageView"; ReactApplicationContext mCallerContext; public ReactImageManager(ReactApplicationContext reactContext) { mCallerContext = reactContext; } @Override public String getName() { return REACT_CLASS; }
视图在createViewInstance
中创建,且应当把自己初始化为默认的状态。所有属性的设置都通过后续的updateView
来进行。
1 2 3 4 | @Override public ReactImageView createViewInstance(ThemedReactContext context) { return new ReactImageView(context, Fresco.newDraweeControllerBuilder(), null , mCallerContext); } |
1 | 3 . 通过 @ReactProp (或 @ReactPropGroup )注解来导出属性的设置方法。 |
3. 通过@ReactProp
(或@ReactPropGroup
)注解来导出属性的设置方法
要导出给 JavaScript 使用的属性,需要申明带有@ReactProp
(或@ReactPropGroup
)注解的设置方法。方法的第一个参数是要修改属性的视图实例,第二个参数是要设置的属性值。方法的返回值类型必须为void
,而且访问控制必须被声明为public
。JavaScript 所得知的属性类型会由该方法第二个参数的类型来自动决定。支持的类型有:boolean
, int
, float
, double
, String
, Boolean
, Integer
, ReadableArray
, ReadableMap
。
@ReactProp
注解必须包含一个字符串类型的参数name
。这个参数指定了对应属性在 JavaScript 端的名字。
name
,@ReactProp
注解还接受这些可选的参数:defaultBoolean
, defaultInt
, defaultFloat
。这些参数必须是对应的基础类型的值(也就是boolean
, int
, float
),这些值会被传递给 setter 方法,以免 JavaScript 端某些情况下在组件中移除了对应的属性。注意这个"默认"值只对基本类型生效,对于其他的类型而言,当对应的属性删除时,null
会作为默认值提供给方法。使用@ReactPropGroup
来注解的设置方法和@ReactProp
不同。请参见@ReactPropGroup
注解类源代码中的文档来获取更多详情。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @ReactProp (name = "src" ) public void setSrc(ReactImageView view, @Nullable ReadableArray sources) { view.setSource(sources); } @ReactProp (name = "borderRadius" , defaultFloat = 0f) public void setBorderRadius(ReactImageView view, float borderRadius) { view.setBorderRadius(borderRadius); } @ReactProp (name = ViewProps.RESIZE_MODE) public void setResizeMode(ReactImageView view, @Nullable String resizeMode) { view.setScaleType(ImageResizeMode.toScaleType(resizeMode)); } |
注册ViewManager
在 Java 中的最后一步就是把视图控制器注册到应用中。这和原生模块的注册方法类似,唯一的区别是我们把它放到createViewManagers
方法的返回值里。
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new ReactImageManager(reactContext)
);
}
5. 实现对应的 JavaScript 模块
propTypes
来规范接口定义,这一做法已不再支持)。1 2 3 4 5 6 7 8 9 10 11 12 | // ImageView.js import { requireNativeComponent } from 'react-native' ; /** * Composes `View`. * * - src: string * - borderRadius: number * - resizeMode: 'cover' | 'contain' | 'stretch' */ module.exports = requireNativeComponent( 'RCTImageView' ); |
requireNativeComponent
目前只接受一个参数,即原生视图的名字。如果你还需要做一些复杂的逻辑譬如事件处理,那么可以把原生组件用一个普通 React 组件封装。后文的MyCustomView
例子里演示了这种用法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」