Zoomlayout: لا تؤدي التغييرات في العرض / الارتفاع في ZoomLayout إلى تحديث تحول الطفل للحفاظ على عمل القص المركزي

تم إنشاؤها على ١٦ أكتوبر ٢٠٢٠  ·  5تعليقات  ·  مصدر: natario1/ZoomLayout

صف الخلل

  • إصدار المكتبة: 1.8.0
  • قابل للتكرار في التطبيق التجريبي الرسمي: نعم
  • إصدار الجهاز / Android: Pixel 3، API 29

أنا أستخدم ZoomLayout لإظهار صور عمودية / أفقية. لقد قمت بتعطيل Zoom & OverScroll. أنا أستخدم التحريك الأفقي والعمودي مع CenterCrop فقط. في وقت واحد ، يمكن إجراء تحريك اتجاه واحد فقط ، كما هو متوقع (نظرًا لتعطيل التكبير / التصغير). هذا يسمح لي بإظهار جزء من الصورة ، بينما يمكن عرض الجزء الآخر باستخدام Pan.

كما فهمت ، يعمل 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

لإعادة إنتاج

خطوات إعادة إنتاج السلوك ، ربما في التطبيق التجريبي:

  1. تعطيل التكبير و OverScroll.
  2. تمكين التحريك الأفقي والعمودي.
  3. ضع عرض الطفل في ZoomLayout في XML. احتفظ بالعرض / الارتفاع لتغليف المحتوى.
  4. أضف منظر طبيعي طويل قابل للرسم. تم اختباره بدقة 780 × 180.
  5. تعيين هذا الرسم كخلفية لعرض الطفل في ZoomLayout في XML.
  6. تشغيل ، وتنفيذ Pan أفقيًا.
  7. استخدم زرًا لزيادة ارتفاع ZoomLayout. لا يتم إجراء التحول على الطفل.

سلوك متوقع

عندما يتغير ارتفاع الحاوية ، يتم تطبيق التحويل الفرعي للحفاظ على CenterCrop.

تنسيق XML (تكبير / تصغير موسع)

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

لقطات

Screenshot
Screenshot

السجلات

انطلقت

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

لم يتم تحويل الطفل للحفاظ على وظيفة centcrop.

APK

سيوفر إذا لزم الأمر ، ولكن من السهل جدًا استخدام خطوات الاستنساخ.

enhancement discussion

التعليق الأكثر فائدة

تعجبني الطريقة التي تعمل بها الآن ، يمكن أن يتغير حجم الحاوية لأسباب عديدة وإذا كان المحتوى قد تم تكبيره / تصغيره بالفعل ، فلا أعتقد أنه يجب علينا إعادة تطبيق التحويل. يجب أن تكون قادرًا على تحقيق ما تريد مثل هذا:

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 () أو شيء من هذا القبيل

ال 5 كومينتر

لقد استخدمت الكود أدناه للتغلب على هذا.

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 المسألة. من الواضح ، الآن أنني أعرف سبب إعادة تعيين Pan (تلميح # التخطيط العالمي).

لذلك ، ما زلت أبحث عن طريقة لإخبار 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 ، فلن يكون هذا مهمًا.

أيضًا ، أنا مشغول برمز المكتبة اعتبارًا من يوم الثلاثاء. لا أعرف ~ الكثير ~ أي شيء عن كيفية عمل المصفوفات أو المتجهات أو التظليل. أحاول القراءة والتعديل للتعلم. لكن ، لقد جربت اقتراحك بالفعل قبل الإبلاغ عن المشكلة. كنتيجة لذلك ، تم تمكين Pan لكل من الاتجاهات الأفقية والرأسية. ولم يعد القص المركزي متاحًا حيث يبدو أن المحتوى / الطفل قد تم تكبيره.

شكرا لك على مساعدتك. أنا آسف لأني استغرقت وقتًا أطول للرد.

rupinderjeet حاولت إعادة إنتاج LayoutParams المعدل على مثيل ZoomLayout ، أحصل على رسالة الخطأ الخاصة بنا:

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

هل فاتني شيء؟

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

wakaztahir picture wakaztahir  ·  5تعليقات

aouledissa picture aouledissa  ·  10تعليقات

MohamedMedhat1998 picture MohamedMedhat1998  ·  6تعليقات

Yahor10 picture Yahor10  ·  5تعليقات

natario1 picture natario1  ·  13تعليقات