Zoomlayout: Mudanças na largura / altura do ZoomLayout não atualizam a transformação filho para manter o corte central funcionando

Criado em 16 out. 2020  ·  5Comentários  ·  Fonte: natario1/ZoomLayout

Descreva o bug

  • Versão da biblioteca: 1.8.0
  • Reproduzível no aplicativo de demonstração oficial: Sim
  • Versão do dispositivo / Android: Pixel 3, API 29

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

Reproduzir

Etapas para reproduzir o comportamento, possivelmente no aplicativo de demonstração:

  1. Desative Zoom e OverScroll.
  2. Habilite Pan para Horizontal e Vertical.
  3. Coloque uma visão filha no ZoomLayout em XML. Mantenha a largura / altura para envolver o conteúdo.
  4. Adicione um drawable longo de paisagem. Testado com 780 x 180.
  5. Defina este drawable como plano de fundo para a visualização filha em ZoomLayout em XML.
  6. Corra, execute Pan horizontalmente.
  7. Use um botão para aumentar a altura do ZoomLayout. A transformação na criança não é realizada.

Comportamento esperado

Quando a altura do contêiner muda, a transformação filho é aplicada para manter CenterCrop.

Layout XML (Extended ZoomLayout)

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)
}

Capturas de tela

Screenshot
Screenshot

Histórico

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.

APK

Fornecerá, se necessário, etapas de reprodução muito fáceis de usar.

enhancement discussion

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:

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

Todos 5 comentários

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?

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

wakaztahir picture wakaztahir  ·  5Comentários

YiHaoHuang picture YiHaoHuang  ·  10Comentários

MohamedMedhat1998 picture MohamedMedhat1998  ·  6Comentários

aouledissa picture aouledissa  ·  10Comentários

kuoliangkwong picture kuoliangkwong  ·  4Comentários