我正在使用 ZoomLayout 来显示纵向/横向图像。 我已禁用 Zoom 和 OverScroll。 我仅将水平和垂直平移与 CenterCrop 一起使用。 正如预期的那样,一次只能执行一个方向平移(因为禁用了缩放)。 这允许我显示图像的一部分,而另一部分可以使用 Pan 查看。
据我所知, centercrop 的工作原理是将containerHeight
对齐childHeight
或containerWidth
对齐childWidth
。 对? 想象一下将风景/肖像图像加载到方形 ImageView 中。 对于横向图像, childHeight
将与containerHeight
对齐以执行 centercrop,现在可以水平执行 pan。 同样,对于纵向图像,可以垂直执行平移。
这工作正常。
但是,如果我像这样更改 ZoomLayout 的宽度/高度,则转换不会应用于子视图。
val layoutParams = zoomLayout.layoutParams
layoutParams.width = layoutParams.width + changedWidth
layoutParams.height = layoutParams.height + changedHeight
zoomLayout.layoutParams = layoutParams
重现行为的步骤,可能在演示应用程序中:
当容器高度发生变化时,会应用子变换来保持 CenterCrop。
init {
setHorizontalPanEnabled(true)
setVerticalPanEnabled(true)
setOverScrollHorizontal(false)
setOverScrollVertical(false)
setAlignment(Alignment.TOP or Alignment.LEFT)
setHasClickableChildren(true)
setTransformation(
ZoomApi.TRANSFORMATION_CENTER_CROP,
ZoomApi.TRANSFORMATION_GRAVITY_AUTO
)
setZoomEnabled(false)
}
推出
I/ZoomLayout: setHasClickableChildren: old: false new: false
I/ZoomLayout: setHasClickableChildren: old: false new: true
加载可在孩子上绘制的水平背景。
W/ZoomEngine: onMatrixSizeChanged: firstTime: true oldZoom: NaN transformation: 1 transformationZoom: 0.0
I/ZoomEngine: computeTransformationZoom centerCrop scaleX: 1.0042135 scaleY: 5.860656
I/ZoomEngine: onMatrixSizeChanged: newTransformationZoom: 5.860656 newRealZoom: 5.8606563 newZoom: 1.0000001
使用上面的代码增加 ZoomLayout 高度。
W/ZoomEngine: onMatrixSizeChanged: firstTime: false oldZoom: 5.8606563 transformation: 1 transformationZoom: 5.860656
I/ZoomEngine: computeTransformationZoom centerCrop scaleX: 1.0042135 scaleY: 6.2704916
I/ZoomEngine: onMatrixSizeChanged: newTransformationZoom: 6.2704916 newRealZoom: 5.8606563 newZoom: 0.93464065
Child 不会被转换以保持 centercrop 功能。
如果需要,将提供,但非常易于使用的复制步骤。
我使用下面的代码来解决这个问题。
val layoutParams = zoomLayout.layoutParams
layoutParams.width = layoutParams.width + changedWidth
layoutParams.height = layoutParams.height + changedHeight
zoomLayout.layoutParams = layoutParams
zoomLayout.engine.setContainerSize(
layoutParams.width.toFloat(),
layoutParams.height.toFloat(),
applyTransformation = false // not applying transformation
)
而且,ZoomLayout 的onGlobalLayout()
另一个变化
engine.setContentSize(
child.width.toFloat(),
child.height.toFloat(),
applyTransformation = true // <-- this change
)
这样做对我有帮助。 子项与父项正确对齐以保持中心裁剪功能。 但是,这个代码产生了#185 问题。 显然,现在我知道 Pan 重置的原因(提示#global-layout)。
因此,我仍在寻找一种方法来告诉 ZoomLayout 在容器宽度/高度更改时对子项应用转换。 如果我继续尝试使用 hacks,我只会有更多的错误。 你在这方面工作过,你比我更清楚。 请指导我。
谢谢你的详细报告。
我认为这是 ZoomLayout 的一个普遍问题,在更改容器的尺寸时还没有真正定义行为,因为我们希望容器保持其尺寸,如果我错了,请纠正我@natario1。 所以据我所知,这更像是一个功能请求而不是一个错误。
如果我们想支持这一点,我认为我们需要讨论预期的行为应该是什么样子,以及开发人员应该如何偏离它。
我喜欢它现在的工作方式,容器大小可能因多种原因而改变,如果内容已经缩放/平移,我认为我们不应该重新应用转换。 你应该能够像这样实现你想要的:
zoomLayout.layoutParams = layoutParams
zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)
或者像这样
zoomLayout.layoutParams = layoutParams
zoomLayout.post {
zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)
}
我们可以使用 syncTransformation() 函数或类似的东西使这更容易
@markusressel好的,我明白了。 另外,我觉得我想做的只是使用这个库的 25% 的潜力。 禁用库的用途实际上是在违背它并期望它能够工作。 我所需要的只是带有平移和抛掷的中心裁剪。 如果您有任何建议,请提出。 谢谢。
容器大小可能因多种原因而改变,如果内容已经缩放/平移,我认为我们不应该重新应用转换
@natario1如果这是预期的/需要的,则此行为应该有一个选择加入标志。 对我来说,这感觉就像是对默认期望的反感。 当应用 center-crop 并更改容器大小时,应保持 center-crop。 尽管如果我们不支持 ZoomLayout 中的大小更改,那么这甚至无关紧要。
另外,我从星期二开始研究图书馆的代码。 我对矩阵、向量或着色器的工作原理知之甚少。 我尝试阅读和修改来学习。 但是,在报告问题之前,我已经尝试了您的建议。 因此,水平和垂直方向都启用了平移。 并且,由于内容/子项似乎被缩放,因此中心裁剪不再可用。
感谢您的帮助。 很抱歉我花了更长的时间来回复。
@rupinderjeet我试图重现您的示例,但是当将修改后的LayoutParams
应用于ZoomLayout
实例时,我收到了我们自己的错误消息:
java.lang.RuntimeException: ZoomLayout must be used with fixed dimensions (e.g. match_parent)
我错过了什么吗?
最有用的评论
我喜欢它现在的工作方式,容器大小可能因多种原因而改变,如果内容已经缩放/平移,我认为我们不应该重新应用转换。 你应该能够像这样实现你想要的:
或者像这样
我们可以使用 syncTransformation() 函数或类似的东西使这更容易