按 id 从本机代码更新 ImageView 本机 UI 组件



我正在使用第三方红外热像仪,我正在尝试从热像仪实时流式传输预览。我能够渲染 ImageView,并且通过记录原始图像缓冲区,我可以看到我的图像正在成功检索。但是,当我尝试更新 UI 线程上的视图时,我无法从当前活动中按 Id 找到视图,因此我可以更新 ImageView 位图。

我的第一个方法是使用设备事件发射器发出图像的base64编码表示形式以做出本机反应,但这会导致冻结等,所以我放弃了这种方法。

现在,我正在使用SimpleViewManager创建一个ImageView并分配一个id。然后,在接收图像流的侦听器(创建为本机模块)中,我尝试通过当前活动中的 id 查找该 ImageView 的图像位图来设置该图像视图的图像位图。但是,我无法按 id 找到视图(它总是空)。

这是我扩展ReactContextBaseJavaModule的类的一部分,并注册为本机模块。上下文是通过调用getCurrentActivity()检索的活动。

@Override
public void accept(ThermalImage thermalImage) {
try {
final Bitmap bmp = BitmapAndroid.createBitmap(thermalImage.getImage()).getBitMap();
final Activity activity = (Activity) context;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e(TAG, "Running on ui thread!!");
final ImageView imageView = activity.findViewById(R.id.thermal_image);
if (imageView != null) {
Log.e(TAG, "IMAGE VIEW NOT NULL");
imageView.setImageBitmap(bmp);
}
}
});
Log.e(TAG, "Image Received");
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}

注册为本机 UI 模块的视图管理器

public class ThermalImageViewManager extends SimpleViewManager<ReactImageView> {
public static final String REACT_CLASS = "RCTThermalImageView";
@Nonnull
@Override
public String getName() {
return REACT_CLASS;
}
@Nonnull
@Override
protected ReactImageView createViewInstance(@Nonnull ThemedReactContext reactContext) {
final ReactImageView imageView = new ReactImageView(reactContext, Fresco.newDraweeControllerBuilder(), null, null);
imageView.setId(R.id.thermal_image);
return imageView;
}
}

这是呈现视图然后启动流的反应代码。

onComponentDidMount() {
ThermalImageCapture.startStream();
}
render() {
return (
<View style={{justifyContent: 'center', height: '100%', backgroundColor: "#231F20"}}>
<Button onPress={this.handleClick}><Text>Camera</Text></Button>
<ThermalImageView style={{width: 500, height: 500, backgroundColor: "white"}}></ThermalImageView>
</View>
);
}

我想在这种情况下,我应该能够通过 id 访问视图,但事实似乎并非如此。任何更好的办法也将不胜感激。

对于遇到这种情况的任何人,我想出了一种方法来做到这一点。关键是使用 AddUIBlockMethod 获取 ImageView by 标记,然后将视图传递给我的侦听器设置位图。

例:

@ReactMethod
public void startStream(final int tag) {
context.getNativeModule(UIManagerModule.class).addUIBlock(new UIBlock() {
@Override
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
final ReactImageView imageView = (ReactImageView) nativeViewHierarchyManager.resolveView(tag);
if (imageView != null) {
streamListener = configureListener(context, imageView);
streamListener.start();
}
}
});
}
componentDidMount() {
startStream(findNodeHandle(this.imageView));
}
componentWillUnmount() {
stopStream();
}
render() {
return (
<View style={{justifyContent: 'center', height: '100%', backgroundColor: "#231F20"}}>
<Button onPress={this.handleClick}><Text>Camera</Text></Button>
<Image
ref={ref => this.imageView = ref}
style={{width: 500, height: 500}}/>
</View>
);
}

最新更新