Estou usando o ZoomLayout para mostrar imagens em retrato / paisagem. Desativei o Zoom e o OverScroll. Estou usando Pan horizontal e vertical apenas com CenterCrop. Ao mesmo tempo, apenas uma panorâmica de direção pode ser executada, como esperado (porque o zoom está desativado). Isso me permite mostrar uma parte da imagem, enquanto a outra parte pode ser visualizada usando Pan.
Como entendi, o corte central funciona alinhando containerHeight
a childHeight
ou containerWidth
a childWidth
. Direito? Imagine carregar imagens de paisagem / retrato em um ImageView quadrado. Para imagens de paisagem, childHeight
será alinhado com containerHeight
para realizar o corte central, e agora, o movimento panorâmico pode ser executado horizontalmente. Da mesma forma, para imagens de retrato, a panorâmica pode ser executada verticalmente.
Isso funciona bem.
Mas, se eu alterar a largura / altura do ZoomLayout assim, a transformação não será aplicada na visualização filho.
val layoutParams = zoomLayout.layoutParams
layoutParams.width = layoutParams.width + changedWidth
layoutParams.height = layoutParams.height + changedHeight
zoomLayout.layoutParams = layoutParams
Etapas para reproduzir o comportamento, possivelmente no aplicativo de demonstração:
Quando a altura do contêiner muda, a transformação filho é aplicada para manter 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)
}
Lançado
I/ZoomLayout: setHasClickableChildren: old: false new: false
I/ZoomLayout: setHasClickableChildren: old: false new: true
Carregar Drawable de fundo horizontal na criança.
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
Aumente a altura do ZoomLayout usando o código acima.
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
O filho não é transformado para manter a funcionalidade de corte central.
Fornecerá, se necessário, etapas de reprodução muito fáceis de usar.
Usei o código abaixo para contornar isso.
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
)
E outra mudança no onGlobalLayout()
do ZoomLayout
engine.setContentSize(
child.width.toFloat(),
child.height.toFloat(),
applyTransformation = true // <-- this change
)
Fazer isso me ajuda. O filho está alinhado corretamente com o pai para manter a funcionalidade de corte central. Mas, este código gera o problema # 185. Claramente, agora eu sei a razão pela qual o Pan é redefinido (dica # global-layout).
Portanto, ainda estou procurando uma maneira de dizer ao ZoomLayout para aplicar a transformação no filho quando a largura / altura do contêiner for alterada. Se eu continuar tentando usar hacks, terei apenas mais bugs. Você trabalhou nisso, você sabe melhor do que eu. Por favor me guie.
Obrigado pelo relatório detalhado.
Acho que este é um problema geral do ZoomLayout não ter realmente um comportamento definido ao alterar as dimensões do contêiner, já que esperamos que o contêiner mantenha suas dimensões, corrija-me se eu estiver errado @ natario1. Pelo que entendi, isso é mais uma solicitação de recurso do que um bug.
Se quisermos dar suporte a isso, acho que precisamos discutir sobre como deve ser o comportamento esperado e como os desenvolvedores devem ser capazes de desviá-lo.
Gosto de como funciona agora, o tamanho do contêiner pode mudar por vários motivos e se o conteúdo já foi ampliado / deslocado, não acho que devemos reaplicar a transformação. Você deve ser capaz de alcançar o que deseja desta forma:
zoomLayout.layoutParams = layoutParams
zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)
Ou talvez assim
zoomLayout.layoutParams = layoutParams
zoomLayout.post {
zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)
}
Poderíamos tornar isso mais fácil com uma função syncTransformation () ou algo parecido
@markusressel Ok, eu entendo. Além disso, acho que o que quero fazer é usar apenas 25% do potencial desta biblioteca. Desativar a finalidade da biblioteca é, na verdade, ir contra e esperar que funcione. Tudo que eu preciso é de cultura central com pan e fling. Se você tem algo a sugerir, por favor, faça. Obrigado.
o tamanho do contêiner pode mudar por vários motivos e se o conteúdo já foi ampliado / deslocado, não acho que devemos reaplicar a transformação
@ natario1 Se isso for esperado / necessário, deve haver um sinalizador de
Além disso, estou envolvido com o código da biblioteca de terça-feira. Eu não sei ~ muito ~ nada sobre como matrizes, vetores ou shaders funcionam. Tento ler e modificar para aprender. Porém, já experimentei sua sugestão antes de relatar o problema. Como resultado disso, o Pan é habilitado para as direções horizontal e vertical. E, o corte central não está mais disponível, pois o conteúdo / filho parece estar ampliado.
Obrigado pela ajuda. Lamento ter demorado muito mais para responder.
@rupinderjeet Tentei reproduzir seu exemplo, mas ao aplicar o LayoutParams
modificado à instância ZoomLayout
, recebo nossa própria mensagem de erro:
java.lang.RuntimeException: ZoomLayout must be used with fixed dimensions (e.g. match_parent)
Estou esquecendo de algo?
Comentários muito úteis
Gosto de como funciona agora, o tamanho do contêiner pode mudar por vários motivos e se o conteúdo já foi ampliado / deslocado, não acho que devemos reaplicar a transformação. Você deve ser capaz de alcançar o que deseja desta forma:
Ou talvez assim
Poderíamos tornar isso mais fácil com uma função syncTransformation () ou algo parecido