在 React Native 中调用 Android 自定义控件(也称为"原生 UI 组件")涉及以下核心步骤,需同时处理 Android 原生代码和 JavaScript 封装逻辑。以下是实现流程及关键代码示例:
⚙️ 1. Android 原生自定义 View 实现
自定义一个继承自 View
的类,并实现其属性和绘制逻辑:
java
// GradientColorView.java
public class GradientColorView extends View {
private GradientDrawable mDrawable;
private int mStartColor;
private int mEndColor;
public GradientColorView(Context context) {
super(context);
mDrawable = new GradientDrawable(Orientation.LEFT_RIGHT, null);
}
public void setStartColor(int color) {
mStartColor = color;
invalidate(); // 触发重绘
}
public void setEndColor(int color) {
mEndColor = color;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mDrawable.setColors(new int[]{mStartColor, mEndColor});
mDrawable.setBounds(0, 0, getWidth(), getHeight());
mDrawable.draw(canvas);
}
}
关键点:
- 通过
setStartColor
/setEndColor
暴露属性修改接口。 - 调用
invalidate()
确保属性更新后刷新视图。
🧩 2. 创建 ViewManager 管理自定义 View
继承 SimpleViewManager<T>
类,将 Java 方法映射为 RN 属性:
typescript
// GradientColorViewManager.java
public class GradientColorViewManager extends SimpleViewManager<GradientColorView> {
public static final String REACT_CLASS = "RCTGradientColorView";
@Override
public String getName() {
return REACT_CLASS; // JS 端引用此名称
}
@Override
protected GradientColorView createViewInstance(ThemedReactContext context) {
return new GradientColorView(context);
}
@ReactProp(name = "startColor", customType = "Color")
public void setStartColor(GradientColorView view, @Nullable Integer color) {
view.setStartColor(color); // 接收 JS 传入的颜色值
}
@ReactProp(name = "endColor", customType = "Color")
public void setEndColor(GradientColorView view, @Nullable Integer color) {
view.setEndColor(color);
}
}
关键注解:
@ReactProp
:定义 JS 属性名与类型(customType="Color"
自动转换颜色字符串为整数)。- 方法需为
public void
,首个参数为视图实例。
📝 3. 注册 ViewManager 到 ReactPackage
在自定义的 ReactPackage
中将 ViewManager
加入注册列表:
typescript
// CustomReactPackage.java
public class CustomReactPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext context) {
return Arrays.<ViewManager>asList(
new GradientColorViewManager() // 注册自定义 ViewManager
);
}
@Override
public List<NativeModule> createNativeModules(...) {...} // 若无原生模块,返回空列表
}
集成到 RN :
在 MainApplication.java
的 getPackages()
中添加此 Package:
arduino
.addPackage(new CustomReactPackage()) // 注册自定义包
🌐 4. JavaScript 端封装组件
使用 requireNativeComponent
将原生组件映射到 JS:
php
// GradientColorView.js
import { requireNativeComponent, ViewPropTypes } from 'react-native';
const NativeGradientColorView = requireNativeComponent('RCTGradientColorView', {
propTypes: {
startColor: PropTypes.string, // 颜色字符串(如 "#FF0000")
endColor: PropTypes.string,
...ViewPropTypes // 继承基础 View 属性(如 style)
}
});
export default NativeGradientColorView;
注意事项:
- 名称
'RCTGradientColorView'
需与ViewManager.getName()
完全一致。 - 属性类型(如
PropTypes.string
)需与@ReactProp
注解的 Java 类型匹配。
⚡️ 5. 在 RN 中使用自定义组件
导入封装后的组件并传递属性:
ini
import GradientColorView from './GradientColorView';
<GradientColorView
style={{ width: 200, height: 200 }}
startColor="#FF0000" // 红色起始
endColor="#0000FF" // 蓝色结束
/>
🧪 调试常见问题
-
属性未生效:
- 检查
@ReactProp
的name
与 JS 属性名是否一致。 - 确保 Android 的
setColor()
等方法调用了invalidate()
。
- 检查
-
类型转换错误:
- 颜色需通过
processColor()
转换(若未用customType="Color"
)。
- 颜色需通过
-
组件未注册:
- 确认
ViewManager
已添加到ReactPackage
并在getPackages()
加载。
- 确认
🔚 总结流程
graph TD
A[Android 自定义 View] --> B[创建 ViewManager 映射属性]
B --> C[注册 ViewManager 到 ReactPackage]
C --> D[JS 端 requireNativeComponent 封装]
D --> E[RN 中使用组件传参]
通过以上步骤,RN 即可调用高性能的 Android 原生 UI 组件,适用于需要复杂绘图、动画或特定平台功能的场景。建议结合 官方文档 和示例代码 进一步调试优化。