翻译:English
- 以下示例优先用 Compose 版本的组件来演示
- ZoomState.zoomable 等价于 ZoomImageView.zoomable
- ZoomState.subsampling 等价于 ZoomImageView.subsampling
ZoomImage 库包含了多个组件可供选择,你可以根据自己的需求选择合适的组件。
不同的组件需要导入不同的依赖,请参考 README 导入对应的依赖
compose android:
- SketchZoomAsyncImage:
推荐使用
- 集成了 Sketch 图片加载库的缩放 Image 组件,用法和 Sketch 的 AsyncImage 组件一样
- 已支持网络图片和子采样,无需做任何额外的工作
- 参考示例 SketchZoomAsyncImageSample
- CoilZoomAsyncImage:
- 集成了 Coil 图片加载库的缩放 Image 组件,用法和 Coil 的 AsyncImage 组件一样
- 已支持网络图片和子采样,无需做任何额外的工作
- 参考示例 CoilZoomAsyncImageSample
- GlideZoomAsyncImage:
- 集成了 Glide 图片加载库的缩放 Image 组件,用法和 Glide 的 GlideImage 组件一样
- 已支持网络图片和子采样,无需做任何额外的工作
- 参考示例 GlideZoomAsyncImageSample
compose multiplatform:
- ZoomImage:
- 最基础的缩放 Image 组件,未集成图片加载库
- 还需要做额外的工作以支持网络图片和子采样
- 参考示例 ZoomImageSample
view:
- SketchZoomImageView:
推荐使用
- 集成了 Sketch 图片加载库的缩放 ImageView
- 已适配 Sketch 支持子采样,无需做任何额外的工作
- 参考示例 SketchZoomImageViewFragment
- CoilZoomImageView:
- 集成了 Coil 图片加载库的缩放 ImageView
- 已适配 Coil 支持子采样,无需做任何额外的工作
- 参考示例 CoilZoomImageViewFragment
- GlideZoomImageView:
- 集成了 Glide 图片加载库的缩放 ImageView
- 已适配 Glide 支持子采样,无需做任何额外的工作
- 参考示例 GlideZoomImageViewFragment
- PicassoZoomImageView:
- 集成了 Picasso 图片加载库的缩放 ImageView
- 已适配 Picasso 支持子采样,无需做任何额外的工作
- 参考示例 PicassoZoomImageViewFragment
- ZoomImageView:
- 最基础的缩放 ImageView,未集成图片加载库
- 还需要做额外的工作以支持网络图片和子采样
- 参考示例 ZoomImageViewFragment
总结:
- 集成了图片加载器的组件无需任何额外的工作即可支持任意来源的图片和子采样功能
- 未集成图片加载器的组件只能显示本地图片,以及需要额外调用
subsampling.setImageSource(ImageSource)
方法以支持子采样功能
SketchZoomAsyncImage(
request = DisplayRequest(LocalContext.current, "http://sample.com/sample.jpg") {
placeholder(R.drawable.placeholder)
crossfade()
},
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
)
CoilZoomAsyncImage(
model = ImageRequest.Builder(LocalContext.current).apply {
data("http://sample.com/sample.jpg")
placeholder(R.drawable.placeholder)
crossfade(true)
}.build(),
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
)
GlideZoomAsyncImage(
model = "http://sample.com/sample.jpg",
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
) {
it.placeholder(R.drawable.placeholder)
}
/*
* android
*/
val state: ZoomState by rememberZoomState()
val context = LocalContext.current
LaunchedEffect(Unit) {
state.subsampling.setImageSource(ImageSource.fromResource(context, R.drawable.huge_image))
}
ZoomImage(
painter = painterResource(R.drawable.huge_image_thumbnail),
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
state = state,
)
/*
* desktop
*/
val state: ZoomState by rememberZoomState()
LaunchedEffect(Unit) {
state.subsampling.setImageSource(ImageSource.fromResource("huge_image.jpeg"))
}
ZoomImage(
painter = painterResource("huge_image_thumbnail.jpeg"),
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
state = state,
)
val sketchZoomImageView = SketchZoomImageView(context)
sketchZoomImageView.displayImage("http://sample.com/sample.jpg") {
placeholder(R.drawable.placeholder)
crossfade()
}
val coilZoomImageView = CoilZoomImageView(context)
coilZoomImageView.load("http://sample.com/sample.jpg") {
placeholder(R.drawable.placeholder)
crossfade(true)
}
val glideZoomImageView = GlideZoomImageView(context)
Glide.with(this@GlideZoomImageViewFragment)
.load("http://sample.com/sample.jpg")
.placeholder(R.drawable.placeholder)
.into(glideZoomImageView)
val picassoZoomImageView = PicassoZoomImageView(context)
picassoZoomImageViewImage.loadImage("http://sample.com/sample.jpg") {
placeholder(R.drawable.placeholder)
}
val zoomImageView = ZoomImageView(context)
zoomImageView.setImageResource(R.drawable.huge_image_thumbnail)
val imageSource = ImageSource.fromResource(context, R.drawable.huge_image)
zoomImageView.subsampling.setImageSource(imageSource)
PicassoZoomImageView 提供了一组专用 API 来监听加载结果并获取 URI,以便支持子采样,因此请不要直接使用官方API 加载图片
zoom 和子采样的 API 封装在不同的类中,compose 版本是 ZoomableState 和 SubsamplingState,view 版本是 ZoomableEngine 和 SubsamplingEngine
示例:
// compose
val state: ZoomState by rememberZoomState()
SketchZoomAsyncImage(
imageUri = "http://sample.com/sample.jpg",
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
state = state,
)
val zoomable: ZoomableState = state.zoomable
val subsampling: SubsamplingState = state.subsampling
// view
val sketchZoomImageView = SketchZoomImageView(context)
val zoomable: ZoomableEngine = sketchZoomImageView.zoomable
val subsampling: SubsamplingEngine = sketchZoomImageView.subsampling
更多缩放、偏移、旋转、子采样、阅读模式、滚动条等功能详细介绍请参考页尾的文档
// compose
val state: ZoomState by rememberZoomState()
SketchZoomAsyncImage(state = state)
val zoomable: ZoomableState = state.zoomable
val subsampling: SubsamplingState = state.subsampling
// view
val sketchZoomImageView = SketchZoomImageView(context)
val zoomable: ZoomableEngine = sketchZoomImageView.zoomable
val subsampling: SubsamplingEngine = sketchZoomImageView.subsampling
- 注意:view 版本的相关属性用 StateFlow 包装,所以其名字相比 compose 版本都以 State 为后缀
zoomable.baseTransform: Transform
: 基础变换信息,包括缩放、偏移、旋转,受 contentScale、alignment 属性以及 rotate() 方法的影响zoomable.userTransform: Transform
: 用户变换信息,包括缩放、偏移、旋转,受用户手势操作、readMode 属性以及 scale()、offset()、locate() 方法的影响zoomable.transform: Transform
: 最终的变换信息,包括缩放、偏移、旋转,等价于baseTransform + userTransform
zoomable.minScale: Float
: 最小缩放比例,用于缩放时限制最小缩放比例以及双击缩放时的一个循环缩放比例zoomable.mediumScale: Float
: 中间缩放比例,用于双击缩放时的一个循环缩放比例zoomable.maxScale: Float
: 最大缩放比例,用于缩放时限制最大缩放比例以及双击缩放时的一个循环缩放比例zoomable.continuousTransformType: Int
: 当前正在进行的连续变换的类型zoomable.contentBaseDisplayRect: IntRect
: content 经过 baseTransform 变换后在 container 中的区域zoomable.contentBaseVisibleRect: IntRect
: content 经过 baseTransform 变换后自身对用户可见的区域zoomable.contentDisplayRect: IntRect
: content 经过 transform 变换后在 container 中的区域zoomable.contentVisibleRect: IntRect
: content 经过 transform 变换后自身对用户可见的区域zoomable.scrollEdge: ScrollEdge
: 当前偏移的边界状态zoomable.containerSize: IntSize
: 当前 container 的大小zoomable.contentSize: IntSize
: 当前 content 的大小zoomable.contentOriginSize: IntSize
: 当前 content 的原始大小subsampling.ready: Boolean
: 是否已经准备好了subsampling.imageInfo: ImageInfo
: 图片的尺寸、格式信息subsampling.exifOrientation: ExifOrientation
: 图片的 exif 信息subsampling.foregroundTiles: List<TileSnapshot>
: 当前前景图块列表subsampling.backgroundTiles: List<TileSnapshot>
: 当前背景图块列表subsampling.sampleSize: Int
: 当前采样大小subsampling.imageLoadRect: IntRect
: 原图上当前实际加载的区域subsampling.tileGridSizeMap: Map<Int, IntOffset>
: 磁贴网格大小映射表
- compose 版本的相关属性是用 State 包装的,在 Composable 函数中直接读取它即可实现监听
- view 的相关属性是用 StateFlow 包装,调用其 collect 函数即可实现监听