首页 > 解决方案 > 如何在 ReactNative 中显示选定的图像

问题描述

我正在尝试显示从专辑中选择的内容,但我遇到了问题。

这是我的代码,第一页显示的是MainScreen,在其中可以按“打开图像浏览器”按钮,然后我重定向到可以选择图像的相册,但是当我单击“完成”时,它应该显示我的图像在MainScreen页面中选择。

但我面临的问题是当我点击“完成”时,我没有看到我选择的图像,所以你能看看代码并告诉我我犯的错误在哪里无法显示选定的图像。

这是MainScreen的代码:

import React, { useState, useEffect } from 'react';
import { View, Platform, Button, Image, ScrollView, Alert } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

function MainScreen(props) {

    const [photos, setPhotos] = useState([]);

    useEffect(() => {
        const { params } = props.route;
        if (params) {
            const { photos } = params;
            if (photos) setPhotos({ photos });
            delete params.photos;
        }
    }, []);

    const renderImage = (item, i) => {
        return (
            <Image
                style={{ height: 100, width: 100 }}
                source={{ uri: item.uri }}
                key={i}
            />
        )
    }


    const { navigate } = props.navigation;

    return (
        <View style={{ flex: 1 }}>
            <Button
                title="Open image browser"
                onPress={async () => {

                    if (Platform.OS !== 'web') {
                        const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
                        if (status !== 'granted') {
                            Alert.alert(
                                'Sorry, we need media library permissions to make this work!',
                            );
                            return;
                        }
                    }

                    navigate('ImageBrowser');
                }}
            />
            <ScrollView>
                {photos.map((item, i) => renderImage(item, i))}
            </ScrollView>
        </View>
    );

}

export default MainScreen;

这是ImageBrowser的代码:

import React, { useEffect, useState } from 'react';
import { StyleSheet, View, Text, TouchableOpacity, ActivityIndicator } from 'react-native';
import * as ImageManipulator from 'expo-image-manipulator';
import { ImageBrowser } from 'expo-image-picker-multiple';

function ImageBrowserScreen(props) {
    const _getHeaderLoader = () => (
        <ActivityIndicator size='small' color={'#0580FF'} />
    );

    const imagesCallback = (callback) => {
        const { navigation } = props;
        props.navigation.setOptions({
            headerRight: () => _getHeaderLoader()
        });

        callback.then(async (photos) => {
            const cPhotos = [];
            for (let photo of photos) {
                const pPhoto = await _processImageAsync(photo.uri);
                cPhotos.push({
                    uri: pPhoto.uri,
                    name: photo.filename,
                    type: 'image/jpg'
                })
            }
            navigation.navigate('Main', { photos: cPhotos });
        })
            .catch((e) => console.log(e));
    };

    const _processImageAsync = async (uri) => {
        const file = await ImageManipulator.manipulateAsync(
            uri,
            [{ resize: { width: 1000 } }],
            { compress: 0.8, format: ImageManipulator.SaveFormat.JPEG }
        );
        return file;
    };

    const _renderDoneButton = (count, onSubmit) => {
        if (!count) return null;
        return <TouchableOpacity title={'Done'} onPress={onSubmit}>
            <Text onPress={onSubmit}>Done</Text>
        </TouchableOpacity>
    }

    const updateHandler = (count, onSubmit) => {
        props.navigation.setOptions({
            title: `Selected ${count} files`,
            headerRight: () => _renderDoneButton(count, onSubmit)
        });
    };

    const renderSelectedComponent = (number) => (
        <View style={styles.countBadge}>
            <Text style={styles.countBadgeText}>{number}</Text>
        </View>
    );


    const emptyStayComponent = <Text style={styles.emptyStay}>Empty =(</Text>;

    return (
        <View style={[styles.flex, styles.container]}>
            <ImageBrowser
                max={4}
                onChange={updateHandler}
                callback={imagesCallback}
                renderSelectedComponent={renderSelectedComponent}
                emptyStayComponent={emptyStayComponent}
            />
        </View>
    );

}
export default ImageBrowserScreen;





const styles = StyleSheet.create({
    flex: {
        flex: 1
    },
    container: {
        position: 'relative'
    },
    emptyStay: {
        textAlign: 'center',
    },
    countBadge: {
        paddingHorizontal: 8.6,
        paddingVertical: 5,
        borderRadius: 50,
        position: 'absolute',
        right: 3,
        bottom: 3,
        justifyContent: 'center',
        backgroundColor: '#0580FF'
    },
    countBadgeText: {
        fontWeight: 'bold',
        alignSelf: 'center',
        padding: 'auto',
        color: '#ffffff'
    }
});

标签: node.jsreactjsimagereact-native

解决方案


我发现了一种“解决方法”,可以使用useEffect钩子显示图像。基本上,您使用空字符串作为初始值创建一个新状态,然后创建图像标签或类:

const [imageSrc, setSrc] = useState("");
// your useEffect method here
useEffect(() => {
   // when the image is meant to be showed
   setSrc(require("<your-path>"));
}, [yourState]);
// Then you create a Image class where you want to show the image
<>
   <Image source={imageSrc} style={styles.yourStyleForImage}/>
</>

推荐阅读