模板版本:v0.4.0

react-native-image-viewing

本项目基于 react-native-image-viewing 开发。

该第三方库的仓库已迁移至 AtomGit,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-image-viewing 版本所属关系如下:

三方库名称 三方库版本 发布信息 支持RN版本 Autolink 编译API版本 社区基线版本 npm地址
@react-native-ohos/react-native-image-viewing ~0.3.0 AtomGit Releases 0.77.* / 0.82.* 否 API12+ 0.2.2 Npm Address
@react-native-ohos/react-native-image-viewing ~0.2.3 Github Releases 0.72.* 否 API12+ 0.2.2 Npm Address
@react-native-oh-tpl/react-native-image-viewing <=0.2.2-0.0.4@deprecated Github Releases 0.72.* No API12+ 0.2.2 Npm Address

1. 安装与使用

进入到工程目录并输入以下命令:

npm

npm install @react-native-ohos/react-native-image-viewing

yarn

yarn add @react-native-ohos/react-native-image-viewing

下面的代码展示了这个库的基本使用场景:

使用时 import 的库名不变。

mport React, { useState } from "react";
import {
  Alert,
  Platform,
  SafeAreaView,
  StatusBar,
  StyleSheet,
  Text,
  View,
  Image, ScrollView, TouchableOpacity
} from "react-native";
import memoize from "lodash/memoize";
import get from "lodash/get";
import ImageViewing from "react-native-image-viewing";
import {ImageSource} from "react-native-image-viewing/dist/@types"

type Props = {
  images: string[];
  onPress: (index: number) => void;
  shift?: number;
};

const IMAGE_WIDTH = 120;
const IMAGE_HEIGH = 120;

const architecture = [
  {
    thumbnail: "https://img.zcool.cn/community/01d191576ccecb0000018c1b64e382.jpg@1280w_1l_2o_100sh.jpg",
    original: "https://img.zcool.cn/community/01d191576ccecb0000018c1b64e382.jpg@1280w_1l_2o_100sh.jpg",
  },
  {
    thumbnail: "https://p0.ssl.qhimgs1.com/sdr/400__/t0461b1cfd7e4ef2b66.jpg",
    original: "https://p0.ssl.qhimgs1.com/sdr/400__/t0461b1cfd7e4ef2b66.jpg",
  },
  {
    thumbnail: "https://p0.ssl.qhimgs1.com/sdr/400__/t017c44dc545b663cce.jpg",
    original: "https://p0.ssl.qhimgs1.com/sdr/400__/t017c44dc545b663cce.jpg",
  }
];


const ImageList = ({ images, shift = 0, onPress }: Props) => (
  <ScrollView
    horizontal
    style={styles1.root}
    contentOffset={{ x: shift * IMAGE_WIDTH, y: 0 }}
    contentContainerStyle={styles1.container}
  >
    {images.map((imageUrl, index) => (
      <TouchableOpacity
        style={styles1.button}
        key={`${imageUrl}_${index}`}
        activeOpacity={0.8}
        onPress={() => onPress(index)}
      >
        {
          typeof imageUrl === 'string' ? <Image source={{ uri: imageUrl }} key={`${index}`} style={styles1.image} /> : <Image source={ imageUrl } key={`${index}`} doubleTapToZoomEnabled={true} style={styles1.image} />
        }
      </TouchableOpacity>
    ))}
  </ScrollView>
);

const styles1 = StyleSheet.create({
  root: { flexGrow: 0 },
  container: {
    flex: 0,
    paddingLeft: 10,
    marginBottom: 10
  },
  button: {
    marginRight: 10
  },
  image: {
    width: IMAGE_WIDTH,
    height: IMAGE_HEIGH,
    borderRadius: 10
  }
});

function App() {
  const [currentImageIndex, setImageIndex] = useState(0);
  const [images, setImages] = useState(architecture);
  const [isVisible, setIsVisible] = useState(false);

  const onSelect = (images, index) => {
    setImageIndex(index);
    setImages(images);
    setIsVisible(true);
  };

  const onRequestClose = () => setIsVisible(false);


  const getImageSource = memoize((images): ImageSource[] =>
    images.map((image) =>
      typeof image.original === "number"
        ? image.original
        : { uri: image.original as string }
    )
  );

  return (
    <SafeAreaView style={styles.root}>
      <ImageList
        images={architecture.map((image) => image.thumbnail)}
        onPress={(index) => onSelect(architecture, index)}
        shift={0.75}
      />
      <ImageViewing
        images={getImageSource(images)}
        imageIndex={currentImageIndex}
        visible={isVisible}
        onRequestClose={onRequestClose}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  root: {
    flex: 1,
    backgroundColor: "#000",
    ...Platform.select({
      android: { paddingTop: StatusBar.currentHeight },
      default: null,
    }),
  },
  about: {
    flex: 1,
    marginTop: -12,
    alignItems: "center",
    justifyContent: "center",
  },
  name: {
    textAlign: "center",
    fontSize: 24,
    fontWeight: "200",
    color: "#FFFFFFEE",
  },
});

是否支持autolink RN框架版本
~0.3.0 否 0.77.* / 0.82.*
~0.2.3 否 0.72.*
<=0.2.2-0.0.4 否 0.72.*

2.1. Overrides RN SDK

为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 oh-package.json5 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。

关于该字段的作用请阅读官方说明

{
  "overrides": {
    "@rnoh/react-native-openharmony": "0.82.7"
  }
}

2.2. 运行

点击右上角的 sync 按钮

或者在命令行终端执行:

cd entry
ohpm install

然后编译、运行即可。

3. 约束与限制

3.1. 兼容性

本文档内容基于以下版本验证通过:

  1. RNOH: 0.72.96; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;
  2. RNOH: 0.72.33; SDK: HarmonyOS NEXT B1; IDE: DevEco Studio: 5.0.3.900; ROM: Next.0.0.71;
  3. RNOH: 0.77.18; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;
  4. RNOH: 0.82.7; SDK: HarmonyOS 6.0.2.130 SDK; IDE: DevEco Studio 6.0.2 Release; ROM: 6.0.0.328;

4. 属性

"Platform"列表示该属性在原三方库上支持的平台。

"HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

Name Description Type Platform Required HarmonyOS Support
images 图片数组用于显示 ImageSource[] All Yes Yes
keyExtractor 唯一标识每张图片 (imageSrc: ImageSource, index: number) => string All No Yes
imageIndex 当前显示图片的索引 number All Yes Yes
visible 控制模态框是否显示 boolean All No Yes
onRequestClose 关闭模态框时调用的函数 function All Yes Yes
onImageIndexChange 图片索引改变时调用的函数 function All No Yes
onLongPress 长按图片时调用的函数 function (event: GestureResponderEvent, image: ImageSource) All No Yes
delayLongPress 长按触发前的延迟时间(毫秒) number All No Yes
animationType 模态框显示动画类型 none, fade, slide All No Yes
presentationStyle 模态框展示样式: 默认为全屏,Android可使用overFullScreen隐藏状态栏 fullScreen, pageSheet, formSheet, overFullScreen All No Partially (Support "fullScreen", "overFullScreen")
backgroundColor 模态框背景颜色(HEX格式) string All No Yes
swipeToCloseEnabled 是否允许上下滑动关闭模态框 boolean All No Yes
doubleTapToZoomEnabled 是否允许双击放大图片 boolean All No Yes
HeaderComponent 头部组件,接收当前图片索引作为参数 component, function All No Yes
FooterComponent 底部组件,接收当前图片索引作为参数 component, function All No Yes

5. 遗留问题

6. 其他

7. 开源协议

本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。