Expo React Native,如何选择从 expo 图像选择器获取的默认本地图像或用户图像

时间:2021-02-10 22:48:38

标签: javascript react-native expo react-native-image-picker

我有一个表单,用户可以选择默认的本地图像或用户照片库中的图像

这是一个 expo snack 使用 android,可以在照片的手机菜单中找到图像

我想将默认的本地图像或用户的图像保存到表单和 redux,目前能够保存选择到表单和 redux 的默认图像。

这是目前有效的方法。 我有一个组件可以获取选定的本地图像并返回一个图像路径女巫是一个数字。该本地图像以表单和 redux 形式保存。目前,用户可以在表单中更改本地图像。

ImgSelector Component:
    
    import React, { useState } from "react";
    import { List, Selector, View, SelectedImg } from "./styles";
    import { FlatList } from "react-native";
    import { defaultImages } from "../../data/defaultImages";

    const FlatlistItem = ({ image, setImg }) => {
    return (
       <Selector onPress={() => setImg(image)}>
         <View>
           <SelectedImg source={image} />
          </View>
       </Selector>
     );
    };

    const ImgSelector = ({ setImg }) => {
    const [selectedId, setSelectedId] = useState(null);
    const renderItem = ({ item }) => (
      <FlatlistItem setImg={setImg} image={item.image} />
    );

    return (
      <View>
        <FlatList
          horizontal
          data={defaultImages}
          renderItem={renderItem}
          keyExtractor={(item, index) => index.toString()}
          extraData={selectedId}
         />
       </View>
     );
   };

   export default ImgSelector;

默认的本地图像是这样存储的,路径是索引,这是一个数字,这部分工作正常。

export const defaultImages = [
    {
      id: “2”,
      image: require("../assets/images/singlepane.png"),
    }
 ]

我有一个 imagePicker 组件,它请求权限并返回一个如下所示的 uri 字符串:

file:/data/data/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FExpoWcPro-a828b17b-dcd7-4a04-93ca-657c8e4e511d/ImagePicker/6106d73f-c81d86-388000000000 >

我的表单组件,用于选择和保存图像:

    import React, { useState } from "react";

    import { Image } from "react-native";

    const CounterForm = ({ navigation, ...props }) => {
    // This is current state for default images that works
    const [imgUrl, setImgUrl] = useState(props.imgUrl || defaultImage);

    const [userImgUri, setUserImgUri] = useState(null);

    // This gets the local image from a componnet
    const handleEditImg = (newImgUrl) => {
      setImgUrl(newImgUrl);
    };

    // This gets image uri from expo image picker
    const handelUserImg = (userUri) => {
      setUserImgUri(userUri);
    };

    // This sends data to a redux action to save
    const handleSubmit = () => {
      props.onFormSubmit({
        id: props.id,
        imgUrl,
      });
      setImgUrl(defaultImage);
    };

    return (
      <FormWrapper>
        <Row>
          <FormButton onPress={() => handleSubmit()}>
            <StyledText title="Save" color={COLORS.appBlue} />
          </FormButton>
        </Row>
        <TopContent>
          {/* I tried this to get user image and displays in form */}
          <Image
            source={{ uri: userImgUri }}
            style={{ width: 100, height: 100 }}
          />

          {/* This current implementation gets local images
          <Image
            source={imgUrl}
            style={{ width: 100, height: 100 }}
          /> */}

          {/* I tried this only gets local images
          {imgUrl ? (
            <Image source={imgUrl} style={{ width: 100, height: 100 }} />
          ) : (
            <Image
              source={{ uri: userImgUri }}
              style={{ width: 100, height: 100 }}
            />
          )} */}
        </TopContent>
        <Row>
          <ImagePicker getUserImg={handelUserImg} />
        </Row>
        <View>
          <ImgSelector setImg={handleEditImg} />
        </View>
      </FormWrapper>
    );
  };

  export default CounterForm;

2 个答案:

答案 0 :(得分:0)

如果您使用最新的 sdk 版本 Expo (40) 和正确的软件包 expo-image-picker,您需要按照 this 说明进行操作。

首先你需要请求权限:

const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
  alert('Sorry, we need camera roll permissions to make this work!');
}

然后调用方法从库中选择图像:

let result = await ImagePicker.launchImageLibraryAsync({
  mediaTypes: ImagePicker.MediaTypeOptions.All,
  allowsEditing: true,
  aspect: [4, 3],
  quality: 1,
});

因此您通过访问 result.uri 获得了图像 uri,您需要保存此值(例如在用户存储中)并通过选择您的存储或默认值(如果没有存储值)来显示它:

<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
  <Button title="Pick an image from camera roll" onPress={pickImage} />

  /** imgUrl = stored image uri, defaultImages[0].image = default image uri */
  <Image source={imgUrl ? { uri: imgUrl } : defaultImages[0].image} />
</View>

答案 1 :(得分:0)

我在 expo snack

中找到了更新的答案
import React, { useState } from "react";
import { List, Selector, View, SelectedImg } from "./styles";
import { FlatList } from "react-native";
import { defaultImages } from "../data";


const FlatlistItem = ({ image, setImg }) => {
  return (
    <Selector onPress={() => setImg(image)}>
      <View>
        <SelectedImg source={{uri: image}} />
      </View>
    </Selector>
  );
};

const ImgSelector = ({ setImg }) => {
  const [selectedId, setSelectedId] = useState(null);
  const renderItem = ({ item }) => {
    return (
    <FlatlistItem setImg={setImg} image={item} />
  )
  }

  return (
    <View>
      <FlatList
        horizontal
        data={defaultImages}
        renderItem={renderItem}
        keyExtractor={(item, index) => index.toString()}
        extraData={selectedId}
      />
    </View>
  );
};

export default ImgSelector;

表格

import React, { useState } from "react";
import {Asset} from 'expo-asset';
import StyledText from "../UiComponents/StyledText";
import { TouchableWithoutFeedback, Keyboard } from "react-native";
import {
  FormWrapper,
  TextInputWrapper,
  TopContent,
  NumberWrapper,
  Row,
  FormButton,
  View,
} from "./styles";
import StyledInput from "../UiComponents/StyledInput";
const defaultImage = Asset.fromModule(require('../assets/komloy.jpg')).uri
import WindowSelector from "../ImgSelector";
import StyledButton from "../UiComponents/StyledButton";
import ImagePicker from "../components/imagePicker";
import { Image } from "react-native";

const DismissKeyboard = ({ children }) => (
  <TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
    {children}
  </TouchableWithoutFeedback>
);

const CounterForm = ({ navigation, ...props }) => {
  const [imgUrl, setImgUrl] = useState(props.imgUrl || defaultImage);
  
  const handleEditImg = (newImgUrl) => {
    setImgUrl(newImgUrl);
  };

  const handelUserImg = (userUri) => {
    setImgUrl(userUri);
  };

  const handleSubmit = () => {
    props.onFormSubmit({
      id: props.id,
      imgUrl
    });
    setImgUrl(defaultImage);
  };

  return (
    <DismissKeyboard>
      <FormWrapper>
        <TopContent>
         <Image
            source={{uri: imgUrl}}
            style={{ width: 100, height: 100 }}
          />
        </TopContent>
        <Row>
          <StyledText title="Select a image" />
          <ImagePicker getUserImg={handelUserImg} />
        </Row>
        <View>
          <WindowSelector setImg={handleEditImg} />
        </View>
      </FormWrapper>
    </DismissKeyboard>
  );
};

export default CounterForm;

数据

 import {Asset} from 'expo-asset';

const imageURI = Asset.fromModule(require('./assets/islands.jpg')).uri
const imageURI2 = Asset.fromModule(require('./assets/maeYai.jpg')).uri

export const defaultImages = [
 imageURI, imageURI2
]