Skip to content

x-previewMedia-s 图片视频混合预览

全屏预览图片与视频的混合列表,对齐微信 wx.previewMedia。横滑翻页、双击与双指缩放、下拉关闭、视频播放、长按菜单。

微信小程序直通 wx.previewMedia,其余四端全部原生自绘,不依赖 uni.previewImage(它只吃图片)。

兼容性

HarmonyiOSAndroidWeb小程序
支持支持支持支持支持(微信)

调用

ts
import { previewMedia, closePreviewMedia, XPreviewMediaOptions } from "@/uni_modules/x-previewMedia-s"

previewMedia({
  sources: [
    { url: "https://example.com/a.jpg" },
    { url: "https://example.com/b.mp4", type: "video", poster: "https://example.com/b.jpg" },
    { url: "/static/local.png" }
  ],
  current: 1,
  showmenu: true,
  onChange: (res) => {
    console.log("切到", res.index, res.type, res.url)
  },
  onLongPress: (res) => {
    console.log("长按", res.url)
  }
} as XPreviewMediaOptions)

方法

名称说明
previewMedia打开全屏预览
closePreviewMedia主动关闭当前预览,微信端不支持

previewMediasuccess 表示预览层已打开,不是关闭时机;要拿关闭时机用 onClose。同一时刻只允许一个预览,重复调用返回 1005

参数

字段默认说明
sources必填资源列表,url 为空的项直接丢弃
current0打开时停留的序号,越界会夹到合法区间
showmenutrue长按时是否弹菜单。关掉后 onLongPress 照常触发,只是不弹层
referrerPolicyno-referrer拉远程资源时是否带 Refererorigin 时带资源自身 origin
indicatordefaultdefault 圆点 / number 数字 / none 不显示,微信端不支持
loopfalse首尾循环滑动,微信端不支持
autoplayfalse视频切到当前页自动起播,默认与微信一致靠点击起播
mutedfalse视频静音起播
menuItems长按菜单文案与顺序,为空则长按只抛事件不弹层,微信端不支持
menuItemColor#000000菜单文字颜色,iOS / Android / 鸿蒙 / Web 生效

sources[] 的字段:

字段默认说明
url必填图片或视频地址,支持 http(s)file://、本地静态资源
typeimageimage / video,缺省按扩展名兜底
poster视频封面,仅 type 为 video 时生效,留空用首帧
liveVideo实况照片配对的 MOV 地址,仅 type 为 image 时生效,只有 iOS 渲染

type 缺省时按扩展名兜底(mp4 mov m4v 3gp mkv webm avi flv ts m3u8 判为视频),判不出当图片。

实况照片

只有 iOS 支持,走系统原生 PHLivePhotoViewurl 传静图,liveVideo 传配对的 MOV:

ts
previewMedia({
  sources: [
    { url: "/static/live/IMG_0001.HEIC", liveVideo: "/static/live/IMG_0001.MOV" }
  ]
} as XPreviewMediaOptions)

交互是点右上角的 LIVE 徽标播放,徽标用的是系统 livePhotoBadgeImage。系统自带的「按住播放」手势被插件主动关掉了,否则会和长按菜单抢同一个手势;长按行为保持不变,仍然是抛 onLongPress 加弹菜单。图片放大或菜单弹着时不响应播放,切页会停掉上一页的播放。

事件

名称触发时机
onChange滑动切换资源后
onLongPress长按发生时,早于菜单弹出
onMenuTap菜单项被点击
onLoadError单项资源加载失败,预览不关闭
onClose预览关闭

这些事件在微信端都不触发,微信的预览界面由系统接管,拿不到内部状态。

长按菜单

菜单是纯壳子:插件负责弹出、命中、收起,不执行任何动作。文案完全由 menuItems 决定,识别码、分享、存相册各接自己已有的插件:

ts
previewMedia({
  sources: [{ url: "https://example.com/qrcode.png" }],
  menuItems: ["分享", "识别", "保存"],
  onMenuTap: (res) => {
    // res.tapIndex 与 menuItems 下标一致,res.itemText 是命中的文案
    if (res.itemText == "分享") shareByMyPlugin(res.url)
    if (res.itemText == "识别") scanByMyPlugin(res.url)
    if (res.itemText == "保存") saveByMyPlugin(res.url)
  }
} as XPreviewMediaOptions)

不传 menuItems 就只有 onLongPress,适合自绘菜单;showmenu: false 也是同样效果。菜单弹着时按返回键先收菜单,再按一次才关预览。

交互

手势行为
横滑翻页,非循环时越界有阻尼;距离不够但甩得快也翻页
双击图片在 1x 与 2x 之间切换,按落点锚定,视频不响应
双指图片缩放,上限 4x,按双指中心锚定;超出 1x~4x 可跟手拉出一段,松手弹回
单指拖动放大后平移画面,松手带惯性滑行;拖出边界有阻尼,松手弹回;未放大时下拉关闭
单击图片关闭预览;放大状态先复位;视频切换播放
长按恒抛 onLongPressshowmenumenuItems 非空时弹菜单
返回Android 返回键、鸿蒙返回手势、Web 浏览器返回都只关预览这一层

错误码

errCode说明
1001系统错误,预览层创建失败
1002参数错误
1003资源列表为空
1005正在预览中
1007当前没有预览,closePreviewMedia 专用
1008当前平台不支持此功能
1009资源加载失败
1010实况照片加载失败,已降级为静态图,仅 iOS

更新日志

1.0.0(2026-08-27)

  • 新增 previewMedia / closePreviewMedia,五端对齐微信 wx.previewMedia
  • 微信小程序直通 wx.previewMedia,Android / iOS / 鸿蒙 / Web 全原生自绘
  • 图片双击与双指缩放、横滑翻页、下拉关闭、视频播放
  • 预览层四端都用独立窗口层:Android Dialog、iOS 独立 UIWindow、鸿蒙 openCustomDialog、Web 压 history 记录,返回只关预览不退页面
  • 长按恒抛 onLongPress,菜单文案由 menuItems 传入,命中项经 onMenuTap 抛出,保存 / 分享 / 识别码全部由页面实现
  • 插件不落库不分享,不申请相册、存储与分享相关权限
  • Android / iOS 播控条图标用插件内独立 remixicon 副本,鸿蒙与 Web 用系统自带控制条
  • sources[] 新增 liveVideo,iOS 走系统 PHLivePhotoView 渲染实况照片,点右上角 LIVE 徽标播放
  • iOS 关掉系统自带的按住播放手势,避免和长按菜单抢手势;放大或菜单弹出时不响应播放
  • 实况照片配对失败或下载失败退回静态图并抛 1010,其余四端忽略 liveVideo 按静图渲染
  • 新增 onLoadError 事件,接出原生层的单项加载失败(含 1009 与 1010),预览不会因此关闭
  • 放大后拖动松手带惯性滑行,拖出边界跟手变重、松手弹回;双指拉出 1x~4x 区间后松手同样弹回
  • 横滑翻页补速度判定,距离不够但甩得快也翻页
  • 四端惯性跑同一套逐帧衰减公式且参数一致,各端驱动器分别是 CADisplayLink / Choreographer / setInterval / requestAnimationFrame,滑行途中可被新触摸立即接手
  • 修复鸿蒙缩放限位按页面尺寸计算的问题,改用 Image onComplete 回填的实际显示尺寸,竖屏看横图不再能把画面拖进黑边
  • 修复 Web 双指缩放每帧都挂 200ms transition 导致缩放滞后手指的问题
最近更新