Zoomlayout: Perubahan pada Lebar/Tinggi ZoomLayout tidak memperbarui transformasi turunan agar pangkas tengah tetap berfungsi

Dibuat pada 16 Okt 2020  ·  5Komentar  ·  Sumber: natario1/ZoomLayout

Jelaskan bugnya

  • Versi perpustakaan: 1.8.0
  • Dapat direproduksi dalam aplikasi demo resmi: Ya
  • Versi perangkat / Android: Pixel 3, API 29

Saya menggunakan ZoomLayout untuk menampilkan gambar potret/lanskap. Saya telah menonaktifkan Zoom & OverScroll. Saya menggunakan Pan horizontal & vertikal dengan CenterCrop saja. Pada satu waktu, hanya satu arah pan yang dapat dilakukan, seperti yang diharapkan (karena zoom dinonaktifkan). Ini memungkinkan saya untuk menampilkan sebagian gambar, sedangkan bagian lainnya dapat dilihat menggunakan Pan.

Seperti yang saya pahami, centercrop bekerja dengan menyelaraskan containerHeight ke childHeight atau containerWidth ke childWidth . Benar? Bayangkan memuat gambar lanskap/potret ke dalam ImageView persegi. Untuk gambar landscape, childHeight akan disejajarkan dengan containerHeight untuk melakukan centercrop, dan sekarang, pan dapat dilakukan secara horizontal. Demikian pula, untuk gambar potret, pan dapat dilakukan secara vertikal.

Ini bekerja dengan baik.

Tapi, jika saya mengubah lebar/tinggi ZoomLayout seperti ini, transformasi tidak diterapkan pada tampilan anak.

val layoutParams = zoomLayout.layoutParams
layoutParams.width = layoutParams.width + changedWidth
layoutParams.height = layoutParams.height + changedHeight
zoomLayout.layoutParams = layoutParams

Untuk Mereproduksi

Langkah-langkah untuk mereproduksi perilaku, mungkin di aplikasi demo:

  1. Nonaktifkan Zoom dan OverScroll.
  2. Aktifkan Pan untuk Horizontal & Vertikal.
  3. Tempatkan View anak di ZoomLayout dalam XML. Pertahankan lebar/tinggi untuk membungkus konten.
  4. Tambahkan drawable lanskap panjang. Diuji dengan 780 x 180.
  5. Setel sumber daya dapat digambar ini sebagai latar belakang untuk tampilan anak di ZoomLayout dalam XML.
  6. Jalankan, lakukan Pan secara horizontal.
  7. Gunakan tombol untuk menambah tinggi ZoomLayout. Transformasi pada anak tidak dilakukan.

Perilaku yang diharapkan

Saat tinggi wadah berubah, transformasi turunan diterapkan untuk mempertahankan CenterCrop.

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

Tangkapan layar

Screenshot
Screenshot

Log

Diluncurkan

I/ZoomLayout: setHasClickableChildren: old: false new: false
I/ZoomLayout: setHasClickableChildren: old: false new: true

Muat Sumber Daya Dapat Digambar di Latar Belakang Horizontal pada Anak.

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

Tingkatkan Tinggi ZoomLayout menggunakan kode di atas.

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

Anak tidak diubah untuk mempertahankan fungsionalitas centercrop.

APK

Akan memberikan jika diperlukan, tetapi sangat mudah untuk menggunakan langkah-langkah reproduksi.

enhancement discussion

Komentar yang paling membantu

Saya suka cara kerjanya sekarang, ukuran wadah dapat berubah karena berbagai alasan dan jika konten sudah diperbesar/digeser, saya tidak berpikir kita harus menerapkan kembali transformasi. Anda harus dapat mencapai apa yang Anda inginkan seperti ini:

zoomLayout.layoutParams = layoutParams
zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)

Atau mungkin seperti ini

zoomLayout.layoutParams = layoutParams
zoomLayout.post {
    zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)
}

Kita bisa membuatnya lebih mudah dengan fungsi syncTransformation() atau sesuatu seperti itu

Semua 5 komentar

Saya menggunakan kode di bawah ini untuk menyiasatinya.

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
)

Dan, perubahan lain pada onGlobalLayout() ZoomLayout

engine.setContentSize(
    child.width.toFloat(), 
    child.height.toFloat(),
    applyTransformation = true // <-- this change
)

Melakukan ini membantu saya. Anak disejajarkan dengan benar dengan induk untuk mempertahankan fungsionalitas centercrop. Tapi, kode ini melahirkan masalah #185. Jelas, sekarang saya tahu alasan mengapa Pan me-reset (petunjuk#global-layout).

Jadi, saya masih mencari cara untuk memberi tahu ZoomLayout untuk menerapkan transformasi pada anak ketika lebar/tinggi wadah diubah. Jika saya terus mencoba menggunakan peretasan, saya hanya akan memiliki lebih banyak bug. Anda telah mengerjakan ini, Anda tahu lebih baik dari saya. Mohon bimbingannya.

Terima kasih atas laporan detailnya.
Saya pikir ini adalah masalah umum ZoomLayout yang belum benar-benar memiliki perilaku yang ditentukan saat mengubah dimensi wadah, karena kami berharap wadah mempertahankan dimensinya, mohon perbaiki saya jika saya salah @ natari1. Jadi seperti yang saya pahami, ini lebih merupakan permintaan fitur daripada bug.

Jika kita ingin mendukung ini, saya pikir kita perlu berdiskusi tentang bagaimana perilaku yang diharapkan akan terlihat, dan bagaimana pengembang harus dapat menyimpang darinya.

Saya suka cara kerjanya sekarang, ukuran wadah dapat berubah karena berbagai alasan dan jika konten sudah diperbesar/digeser, saya tidak berpikir kita harus menerapkan kembali transformasi. Anda harus dapat mencapai apa yang Anda inginkan seperti ini:

zoomLayout.layoutParams = layoutParams
zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)

Atau mungkin seperti ini

zoomLayout.layoutParams = layoutParams
zoomLayout.post {
    zoomLayout.engine.setContainerSize(layoutParams.width, layoutParams.height, true)
}

Kita bisa membuatnya lebih mudah dengan fungsi syncTransformation() atau sesuatu seperti itu

@markusressel Oke, saya mengerti. Juga, saya merasa apa yang ingin saya lakukan hanya menggunakan 25% potensi perpustakaan ini. Menonaktifkan perpustakaan yang dimaksudkan untuk digunakan sebenarnya agak bertentangan dan mengharapkannya berfungsi. Yang saya butuhkan hanyalah tanaman tengah dengan panci dan lemparan. Jika Anda memiliki sesuatu untuk menyarankan, silakan lakukan. Terima kasih.

ukuran wadah dapat berubah karena berbagai alasan dan jika konten sudah diperbesar/digeser, saya tidak berpikir kita harus menerapkan kembali transformasi

@natari1 Jika ini diharapkan/diperlukan, harus ada tanda keikutsertaan untuk perilaku ini. Bagi saya, rasanya seperti anti ekspektasi default. Ketika center-crop diterapkan, dan ukuran wadah diubah, center-crop harus dipertahankan. Meskipun jika kami tidak mendukung perubahan ukuran di ZoomLayout, maka ini tidak masalah.

Juga, saya terlibat dengan kode perpustakaan mulai Selasa. Saya tidak tahu ~banyak~ tentang cara kerja matriks, vektor, atau shader. Saya mencoba membaca dan memodifikasi untuk belajar. Tapi, saya sudah mencoba saran Anda sebelum melaporkan masalah ini. Akibatnya, Pan diaktifkan untuk arah horizontal & vertikal. Dan, crop-tengah tidak lagi tersedia karena konten/anak tampaknya diperbesar.

Terima kasih untuk bantuannya. Saya minta maaf saya mengambil lebih lama untuk merespon.

@rupinderjeet Saya mencoba mereproduksi contoh Anda, tetapi ketika menerapkan LayoutParams dimodifikasi ke instance ZoomLayout , saya mendapatkan pesan kesalahan kami sendiri:

java.lang.RuntimeException: ZoomLayout must be used with fixed dimensions (e.g. match_parent)

Apakah saya melewatkan sesuatu?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

kuoliangkwong picture kuoliangkwong  ·  4Komentar

YiHaoHuang picture YiHaoHuang  ·  10Komentar

lucasrsv picture lucasrsv  ·  3Komentar

MohamedMedhat1998 picture MohamedMedhat1998  ·  6Komentar

Yahor10 picture Yahor10  ·  5Komentar