من الشائع أن تتفاعل مع النقرات المزدوجة للتحكم في التكبير / التصغير. يجب أن تكون هذه ميزة اشتراك في ZoomEngine
، يتم تمكينها افتراضيًا في ZoomImageView
.
@ natario1
في الوقت الحالي ، قمت للتو بتنفيذ هذه الوظيفة بنفسي باستخدام فئة Gesture Listener المخصصة. إليك مقتطف الشفرة الخاص بي إذا احتاجه أي شخص.
private GestureDetector gestureDetector;
private View.OnTouchListener touchListener;
private ZoomImageView selectedImage;
ثم قم بتهيئة هذه المتغيرات:
gestureDetector = new GestureDetector(mContext, new MyGestureListener());
touchListener = new View.OnTouchListener() {
<strong i="11">@Override</strong>
public boolean onTouch(View v, MotionEvent event) {
// pass the events to the gesture detector
// a return value of true means the detector is handling it
// a return value of false means the detector didn't
// recognize the event
selectedImage = (ZoomImageView) v;
return gestureDetector.onTouchEvent(event);
}
};
ثم قم بتعيين مستمع اللمس الخاص بك إلى كائن Zoomimageview:
ZoomImageView image = layout.findViewById(R.id.imageViewItemImageSlider);
image.setOnTouchListener(touchListener);
وهنا فئة MyGestureListener:
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
// <strong i="18">@Override</strong>
// public boolean onDown(MotionEvent event) {
// Log.d("TAG","onDown: ");
//
// // don't return false here or else none of the other
// // gestures will work
// return true;
// }
//
// <strong i="19">@Override</strong>
// public boolean onSingleTapConfirmed(MotionEvent e) {
// Log.i("TAG", "onSingleTapConfirmed: ");
// return true;
// }
//
// <strong i="20">@Override</strong>
// public void onLongPress(MotionEvent e) {
// Log.i("TAG", "onLongPress: ");
// }
<strong i="21">@Override</strong>
public boolean onDoubleTap(MotionEvent e) {
Log.i("TAG", "onDoubleTap: ");
if((selectedImage.getEngine().getZoom() >= 2.75F)) {
selectedImage.getEngine().zoomTo(1F, true);
} else if((selectedImage.getEngine().getZoom() < 1F)) {
selectedImage.getEngine().zoomTo(1F, true);
} else {
selectedImage.getEngine().zoomBy(2F, true);
}
return true;
}
// <strong i="22">@Override</strong>
// public boolean onScroll(MotionEvent e1, MotionEvent e2,
// float distanceX, float distanceY) {
// Log.i("TAG", "onScroll: ");
// return true;
// }
// <strong i="23">@Override</strong>
// public boolean onFling(MotionEvent event1, MotionEvent event2,
// float velocityX, float velocityY) {
// Log.d("TAG", "onFling: ");
// return true;
// }
}
يرجى القيام بتجاوز onScroll (MUST) والطريقة الأخرى (اختيارية في حالتي) والتي ليس لديك أي شيء للتعامل معها لأنها ستتعارض مع حدث اللمس الخاص بـ ZoomImageView وستنشئ مشكلة.
ارجوا ان يساعدك هذا.
أنا أتفاعل حاليًا مع النقر المزدوج لتوسيط الشاشة حيث تم الحدث.
ببساطة عن طريق إضافة هذا:
private val simpleGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
//here is the method for double tap
override fun onDoubleTap(e: MotionEvent): Boolean {
Log.d("OnDoubleTapListener", "onDoubleTap")
centerElement(e.x.absoluteValue,e.y.absoluteValue)
return true
}
})
fun centerElement(clickedX: Float, clickedY: Float) {
val offsetX = (width.absoluteValue) / 2
val offsetY = (height.absoluteValue) / 2
val displacedX = engine.panX.absoluteValue
val displacedY = engine.panY.absoluteValue
val x = (displacedX + clickedX / engine.realZoom) - (offsetX / engine.realZoom)
val y = (displacedY + clickedY / engine.realZoom) - (offsetY / engine.realZoom)
val desiredX = if (x > 0) -x else 0f
val desiredY = if (y > 0) -y else 0f
engine.moveTo(engine.zoom, desiredX, desiredY, true)
}
الآن أحاول التحرك والتكبير بشكل صحيح. يمكنني فتح طلب سحب إذا كنت تريد إنجاحه.
AlvaroFalcon هذا سيكون رائعًا! أستطيع أن أعطيك بعض النصائح.
ZoomEngine
يتفاعل مع التمرير والقذفonScale()
. إنه يعمل مع إحداثيات مركز إيماءة المقياس ويطبق عامل التكبير / التصغير. سيتعين عليك تعيين عامل تكبير / تصغير بنفسك (أعتقد أن zoomIn()
يستخدم 1.3) لكنها نفس المهمة تقريبًاdoubleTapBehavior
؟) والتي يجب أن تحتوي على خيارين على الأقل ("بلا" و "تكبير"). دعنا لا نستخدم أيًا كإعداد افتراضي حتى لا نغير هذا لمن يستخدم lib بالفعل.@ natario1 رائع! سأفعل ذلك عندما يكون لدي بعض الوقت ...
أنا أعمل حاليًا في مشروعي مع فصل يعمل على توسيع نطاق التكبير حتى أقوم بإضافة منطقتي هناك.
أحاول التكبير بالحركة في نفس الوقت باستخدام ذلك ، لكن لا حظ في الوقت الحالي.
شكرا على النصائح!
هل يمكن إضافة إجراء في طريقة moveTo ()؟ ليتم استدعاؤك بعد انتهائها ، أعتقد أنه سيكون أكثر مرونة بهذه الطريقة حتى تتمكن من القيام بأشياء متعددة.
حسنًا ، للتحرك إلى ، تكبير / تصغير ، تكبير / تصغير ، إلخ ...
يمكن أن يكون مثل:
moveTo(zoom, x, y, action : ()->Unit={})
AlvaroFalcon في Kotlin سأفعل ذلك ولكن هذا لا يزال جافا خالصًا. ومع ذلك ، سوف ننتقل إلى Kotlin في المستقبل. في الوقت الحالي ، هناك onIdle()
يمكن لأي شخص الوصول إليه.
AlvaroFalcon هل تمكنت من تحقيق التكبير والتصغير في نفس الوقت؟ تمانع في مشاركة التعليمات البرمجية الخاصة بك؟
لقد قمت بتنفيذ كل من النقر المزدوج والقرص للتكبير. مفتاح حل العمل هو إرفاق كاشف إيماءات النقر / النقر المزدوج بعرض المحتوى داخل تخطيط التكبير / التصغير وتكوين تخطيط التكبير / التصغير لجعل الأطفال قابلين للنقر على صواب. ثم في onTouchEvent لعرض المحتوى ، ارجع بشكل صحيح لاستهلاك أحداث اللمس وتمريرها إلى كاشف الإيماءات. بهذه الطريقة يعمل كل من القرص والتكبير والنقر المزدوج في نفس الوقت. لا يمثل التكبير عند النقر المزدوج مشكلة بعد ذلك.
ومع ذلك ، فقد حاولت أيضًا تكبير المنطقة التي تم النقر عليها مرتين ، وبالنظر إلى كيفية تنفيذ ZoomEngine.moveTo
، فإن الاستيفاء المتزامن للتكبير والتصغير لا يتصرف بشكل صحيح وتتحرك الصورة حول مسارات مختلفة للوصول إلى تكبير الوجهة وعموم. لا يبدو الأمر ممتعًا بصريًا ، لكنني غير قادر على معرفة ما يحدث. أعتقد أن خوارزمية الاستيفاء يجب أن تحسب بشكل مختلف عمومًا الفعلي بناءً على ما هو التكبير الفعلي ، وليس فقط جزء من الرسوم المتحركة.
تكبير المنطقة التي تم النقر عليها مرتين
نعم ، هذا بالضبط ما كنت أحاول القيام به. أي اقتراحات حول كيفية القيام بذلك @ natario1؟
مرحبًا mman
لقد قمنا أيضًا بتطبيق طريقة للتكبير تلقائيًا عندما ينقر المستخدم على الشاشة والرسوم المتحركة للتكبير نوعًا من الدوران نحو الموضع النهائي.
سيكون من الجيد جدًا ، إذا تمكنا من التحكم في هذه الرسوم المتحركة - هل لديك أو لدى الآخرين اقتراحات حول كيفية القيام بذلك؟
شكرا لك مقدما :)
تمكنت من القيام بذلك مع اختراق قذر. إنني أخدع محرك الزوم لأفكر في حدوث ضغط.
class ReflectionHelper {
<strong i="6">@Nullable</strong>
static ScaleGestureDetector.OnScaleGestureListener getScaleDetectorListenerUsingReflection(ZoomEngine zoomEngine) {
try {
Field mScaleDetector = zoomEngine.getClass().getDeclaredField("mScaleDetector");
mScaleDetector.setAccessible(true);
ScaleGestureDetector detector = (ScaleGestureDetector) mScaleDetector.get(zoomEngine);
Field mListener = detector.getClass().getDeclaredField("mListener");
mListener.setAccessible(true);
return (ScaleGestureDetector.OnScaleGestureListener) mListener.get(detector);
} catch (Exception e) {
return null;
}
}
}
private fun simulatePinch(fromScale: Float, toScale: Float, focusX: Float, focusY: Float) {
class MockDetector(var mockScaleFactor: Float, var mockFocusX: Float, var mockFocusY: Float) : ScaleGestureDetector(context, null) {
override fun getScaleFactor() = mockScaleFactor
override fun getFocusX() = mockFocusX
override fun getFocusY() = mockFocusY
}
val mockDetector = MockDetector(fromScale, focusX, focusY)
ValueAnimator.ofFloat(fromScale, toScale).apply {
addUpdateListener { animation ->
mockDetector.mockScaleFactor = animation.animatedValue as Float
zoomEngineScaleListener?.onScale(mockDetector)
}
doOnEnd { zoomEngineScaleListener?.onScaleEnd(mockDetector) }
start()
}
}
مرحبا،
شكرا لهذا الجهد! :)
هذا بالتأكيد يبدو وكأنه طريقة مبتذلة لتحقيق ذلك. أعتقد أننا سنختار العيش مع الرسوم المتحركة للغاية في الوقت الحالي.
شكرا،
نيكولاج
مرحبا،
أي أخبار عن كيفية تحقيق التكبير + التحريك بنقرة مزدوجة؟
شكرا،
كريستوف
التعليق الأكثر فائدة
مرحبا،
أي أخبار عن كيفية تحقيق التكبير + التحريك بنقرة مزدوجة؟
شكرا،
كريستوف