ZoomLayoutを使用してポートレート/風景画像を表示しています。 ズームとオーバースクロールを無効にしました。 CenterCropのみで水平および垂直パンを使用しています。 予想どおり、一度に実行できる方向パンは1つだけです(ズームが無効になっているため)。 これにより、画像の一部を表示し、他の部分はパンを使用して表示できます。
私が理解しているように、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
)
そして、ZoomLayoutのonGlobalLayout()
の別の変更
engine.setContentSize(
child.width.toFloat(),
child.height.toFloat(),
applyTransformation = true // <-- this change
)
これを行うことは私を助けます。 センタークロップ機能を維持するために、子は親と正しく位置合わせされます。 しかし、このコードは#185の問題を生み出します。 明らかに、パンがリセットされる理由がわかりました(ヒント#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これが予想される/必要な場合は、この動作にオプトインフラグが必要です。 私には、それはデフォルトの期待に反しているように感じます。 センタークロップを適用し、コンテナサイズを変更する場合は、センタークロップを維持する必要があります。 ZoomLayoutでサイズ変更をサポートしていない場合でも、これは問題ではありません。
また、火曜日から図書館のコードを扱っています。 行列、ベクトル、またはシェーダーがどのように機能するかについては、私は何も知りません。 私は学習するために読んで修正しようとします。 しかし、私は問題を報告する前にあなたの提案をすでに試しました。 その結果、パンは水平方向と垂直方向の両方で有効になります。 また、コンテンツ/子がズームされているように見えるため、中央の切り抜きは使用できなくなりました。
ご協力ありがとうございました。 返信に時間がかかってすみません。
@rupinderjeet例を再現しようとしましたが、変更されたLayoutParams
をZoomLayout
インスタンスに適用すると、独自のエラーメッセージが表示されます。
java.lang.RuntimeException: ZoomLayout must be used with fixed dimensions (e.g. match_parent)
私は何かが足りないのですか?
最も参考になるコメント
私は今の動作が気に入っています。コンテナのサイズはさまざまな理由で変更される可能性があり、コンテンツがすでにズーム/パンされている場合は、変換を再適用する必要はないと思います。 あなたはこのようにあなたが望むものを達成することができるはずです:
または多分このように
syncTransformation()関数などを使用すると、これを簡単に行うことができます。