React Native类组件中用react-native-translator翻译预测数组
类组件中使用react-native-translator翻译预测数组的解决方案
步骤1:扩展组件状态
在组件的state中添加存储翻译结果的字段,用来保存每个预测项的翻译内容:
state = { isTfReady: false, isModelReady: false, predictions: null, image: null, translatedPredictions: {} // 键为预测的className,值为翻译后的文本 }
步骤2:实现翻译结果回调函数
创建一个方法,在翻译完成后更新组件状态,存储翻译结果:
handleTranslated = (className, translatedText) => { this.setState(prevState => ({ translatedPredictions: { ...prevState.translatedPredictions, [className]: translatedText } })) }
步骤3:修改渲染逻辑,添加翻译组件
你可以选择将翻译结果与原预测项并排显示,或者单独开辟一个翻译结果区域,以下是两种方案:
方案1:与原预测项并排显示
修改render方法中的预测渲染部分:
<View style={styles.predictionWrapper}> {isModelReady && image && ( <Text style={styles.text}> Predictions: {predictions ? '' : 'Predicting...'} </Text> )} {isModelReady && predictions && predictions.map(p => ( <View key={p.className} style={{marginVertical: 8}}> {/* 原预测文本 */} {this.renderPrediction(p)} {/* 翻译组件,针对当前预测的className */} <Translator from="en" to="ms" value={p.className} onTranslated={(translated) => this.handleTranslated(p.className, translated)} /> {/* 显示翻译结果,未完成时显示提示 */} <Text style={[styles.text, {color: '#666'}]}> 翻译: {this.state.translatedPredictions[p.className] || '翻译中...'} </Text> </View> ))} </View>
方案2:单独显示翻译结果区域
在原预测区域下方添加一个新的视图,专门展示翻译后的内容:
{/* 原预测区域 */} <View style={styles.predictionWrapper}> {isModelReady && image && ( <Text style={styles.text}> Predictions: {predictions ? '' : 'Predicting...'} </Text> )} {isModelReady && predictions && predictions.map(p => this.renderPrediction(p))} </View> {/* 新增翻译结果区域 */} {isModelReady && predictions && ( <View style={[styles.predictionWrapper, {marginTop: 20}]}> <Text style={styles.text}>翻译结果:</Text> {predictions.map(p => ( <View key={p.className} style={{marginVertical: 8}}> <Translator from="en" to="ms" value={p.className} onTranslated={(translated) => this.handleTranslated(p.className, translated)} /> <Text style={styles.text}> {p.className} → {this.state.translatedPredictions[p.className] || '翻译中...'} </Text> </View> ))} </View> )}
步骤4:移除错误的Hooks方法
删除组件中定义的translateTo方法,类组件中不能使用useState等React Hooks,所有状态都需要通过组件的state管理。
修改后的完整组件代码片段
class Home extends React.Component { state = { isTfReady: false, isModelReady: false, predictions: null, image: null, translatedPredictions: {} // 新增翻译结果存储 } async componentDidMount() { await tf.ready() this.setState({ isTfReady: true }) this.model = await mobilenet.load() this.setState({ isModelReady: true }) console.log(this.state.isTfReady) this.getPermissionAsync() } getPermissionAsync = async () => { if (Constants.platform.ios) { const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL) if (status !== 'granted') { alert('Sorry, we need camera roll permissions to make this work!') } } } imageToTensor(rawImageData) { const TO_UINT8ARRAY = true const { width, height, data } = jpeg.decode(rawImageData, TO_UINT8ARRAY) const buffer = new Uint8Array(width * height * 3) let offset = 0 for (let i = 0; i < buffer.length; i += 3) { buffer[i] = data[offset] buffer[i + 1] = data[offset + 1] buffer[i + 2] = data[offset + 2] offset += 4 } return tf.tensor3d(buffer, [height, width, 3]) } classifyImage = async () => { try { const imageAssetPath = Image.resolveAssetSource(this.state.image) const response = await fetch(imageAssetPath.uri, {}, { isBinary: true }) const rawImageData = await response.arrayBuffer() const imageTensor = this.imageToTensor(rawImageData) const predictions = await this.model.classify(imageTensor) // 每次分类新图片时,清空之前的翻译结果 this.setState({ predictions, translatedPredictions: {} }) console.log(predictions) } catch (error) { console.log(error) } } selectImage = async () => { try { let response = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.All, allowsEditing: true, aspect: [4, 3] }) if (!response.canceled) { const source = { uri: response.uri } this.setState({ image: source }) this.classifyImage() } } catch (error) { console.log(error) } } renderPrediction = prediction => { return ( <Text key={prediction.className} style={styles.text}> {prediction.className} </Text> ) } // 新增翻译结果处理方法 handleTranslated = (className, translatedText) => { this.setState(prevState => ({ translatedPredictions: { ...prevState.translatedPredictions, [className]: translatedText } })) } render() { const { isTfReady, isModelReady, predictions, image, translatedPredictions } = this.state; return ( <View style={styles.container}> <StatusBar barStyle='light-content' /> <View style={styles.loadingContainer}> <View style={styles.loadingModelContainer}> {(isTfReady && isModelReady) ? ( <Text style={styles.text}> APP IS READY FOR SCANNING! </Text>) : <ActivityIndicator size='small' />} </View> </View> <TouchableOpacity style={styles.imageWrapper} onPress={isModelReady ? this.selectImage : undefined}> {image && <Image source={image} style={styles.imageContainer} />} {isModelReady && !image && ( <Text style={styles.transparentText}>Tap to choose image</Text> )} </TouchableOpacity> {/* 原预测区域 */} <View style={styles.predictionWrapper}> {isModelReady && image && ( <Text style={styles.text}> Predictions: {predictions ? '' : 'Predicting...'} </Text> )} {isModelReady && predictions && predictions.map(p => this.renderPrediction(p))} </View> {/* 新增翻译结果区域 */} {isModelReady && predictions && ( <View style={[styles.predictionWrapper, {marginTop: 20}]}> <Text style={styles.text}>翻译结果:</Text> {predictions.map(p => ( <View key={p.className} style={{marginVertical: 8}}> <Translator from="en" to="ms" value={p.className} onTranslated={(translated) => this.handleTranslated(p.className, translated)} /> <Text style={styles.text}> {p.className} → {translatedPredictions[p.className] || '翻译中...'} </Text> </View> ))} </View> )} <View style={styles.bottom}> <Button style={styles.text} title='SAVE THIS IMAGE' ></Button> </View> <Button title='LIVE Scan Now' onPress={() => this.props.navigation.navigate('ScanScreen')}></Button> </View> ) } }
注意事项
- 确保已正确安装并导入
react-native-translator包 - 在
classifyImage方法中,每次获取新的预测结果时,要清空之前的翻译结果,避免旧数据干扰 - 翻译过程是异步的,所以要显示"翻译中..."的提示,直到翻译完成更新状态
内容的提问来源于stack exchange,提问作者lessy
相关产品推荐
相关产品推荐

