Я использую ZoomLayout для отображения портретных / альбомных изображений. Я отключил Zoom и OverScroll. Я использую горизонтальное и вертикальное панорамирование только с CenterCrop. За один раз, как и ожидалось, можно выполнить панорамирование только в одном направлении (поскольку масштабирование отключено). Это позволяет мне показать часть изображения, в то время как другую часть можно просмотреть с помощью панорамирования.
Как я понял, центральная обрезка работает путем выравнивания containerHeight
с childHeight
или containerWidth
с childWidth
. Верно? Представьте себе загрузку пейзажных / портретных изображений в квадратный ImageView. Для пейзажных изображений childHeight
будет выровнено с containerHeight
для выполнения центрального кадрирования, и теперь панорамирование может выполняться по горизонтали. Точно так же для портретных изображений панорамирование может выполняться по вертикали.
Это прекрасно работает.
Но, если я изменяю ширину / высоту 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
Ребенок не трансформируется для сохранения функциональности посевной.
При необходимости предоставлю, но очень простые в использовании шаги воспроизведения.
Я использовал приведенный ниже код, чтобы обойти это.
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
)
И еще одно изменение в onGlobalLayout()
ZoomLayout
engine.setContentSize(
child.width.toFloat(),
child.height.toFloat(),
applyTransformation = true // <-- this change
)
Это мне помогает. Дочерний элемент правильно выровнен с родительским, чтобы сохранить функциональность центральной обрезки. Но, это код рождения №185 вопроса. Очевидно, теперь я знаю причину, по которой Pan сбрасывается (подсказка # global-layout).
Итак, я все еще ищу способ сообщить ZoomLayout о применении преобразования к дочернему элементу при изменении ширины / высоты контейнера. Если я буду продолжать использовать хаки, у меня будет только больше ошибок. Вы работали над этим, вы знаете лучше меня. Пожалуйста, направь меня.
Спасибо за подробный отчет.
Я думаю, что это общая проблема 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 Если это ожидается / необходимо, для этого поведения должен быть установлен флаг
Еще со вторника занимаюсь кодом библиотеки. Я почти ничего не знаю о том, как работают матрицы, векторы или шейдеры. Я стараюсь читать и изменять, чтобы учиться. Но я уже попробовал ваше предложение, прежде чем сообщать о проблеме. В результате панорамирование включено как для горизонтального, так и для вертикального направлений. И центральное кадрирование больше не доступно, так как контент / дочерний элемент, кажется, увеличен.
Спасибо за помощь. Мне очень жаль, что мне потребовалось больше времени, чтобы ответить.
@rupinderjeet Я попытался воспроизвести ваш пример, но при применении измененного LayoutParams
к экземпляру ZoomLayout
я получил собственное сообщение об ошибке:
java.lang.RuntimeException: ZoomLayout must be used with fixed dimensions (e.g. match_parent)
Я что-то упускаю?
Самый полезный комментарий
Мне нравится, как это работает прямо сейчас, размер контейнера может измениться по многим причинам, и если контент уже был увеличен / панорамирован, я не думаю, что нам следует повторно применять преобразование. Вы должны добиться того, чего хотите, вот так:
Или, может быть, вот так
Мы могли бы упростить это с помощью функции syncTransformation () или чего-то в этом роде.