لا تلمس طفلي (عرض)!

قبل أيام قليلة كنت أعاني من مشكلة ما أبلغ شخص ما عن أحد تطبيقاتي – موجات.

خلفية صغيرة عن التطبيق – إنها لعبة تفاعلية حيث تظهر التموجات بشكل عشوائي على الشاشة ويحتاج المستخدم إلى إخراجها من خلال لمسها لبضع ثوان.

حدث الخطأ عندما لمسنا أولاً عرض الوالدين ثم العرض المتموج. كما ترى في المثال أعلاه ، يقوم المستخدم بلمس الخلفية وبعد ذلك عندما يظهر التموج ويحاول المستخدم لمسه – يتم تعطيل الأحداث التي تظهر على عرض التموج.

في لعبة مثل هذه ، حيث تكون التفاعلات جزءًا مهمًا من اللعبة ، إنه خطأ يجب إصلاحه.

راجع للشغل- يتم دعم اللمس المتعدد في اللعبة ، إذا لمست في نفس العرض أو لمست عرضين تموجات ، فإنها تعمل بشكل جيد. تبدأ المشكلة فقط عندما يتلامس عرض الوالدين.

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

عرض الوالدين هو مجرد عرض RelativeLayout بسيط لم يتم تغييره بأي شكل من الأشكال:

يعد عرض التموج أكثر تعقيدًا بعض الشيء ، ولكن من أجل البساطة ، قمت بإزالة جميع الشفرات غير ذات الصلة:

تكمن المشكلة في أن onTouchEvent في العرض الفرعي لم يتم استدعاؤها عند حدوث اللمسات في العرض الرئيسي ، وهي المسؤولة عن استدعاء onTouchEvent هي dispatchTouchEvent في وجهة نظر الوالدين.

نظرة سريعة على طريقة dispatchTouchEvent في شفرة مصدر RelativeLayout (التنفيذ موجود بالفعل في GroupView) ستظهر لنا رمزًا مرعبًا طويلًا وعامة لجميع الحالات (ولكن لا يزال بإمكاننا تعلم منه كثيرًا ، وأنصحك بقراءة أكبر قدر ممكن من التعليمات البرمجية لمنصة android). يحتوي الكود في الواقع على التعامل مع اللمس في العروض الفرعية والتحقق من حالتها ورؤيتها ، ويحتوي على بعض المستمعين والتعامل مع تسلسل اللمسات ، ويقوم بفحص قائمة اللمسات مرة أخرى وتحديثها.

خلاصة القول- هذه الشفرة تقوم بالعديد من الأشياء التي * نعرف * وهي غير ضرورية في حالتنا.

لهذا السبب يمكننا تنفيذ نسختنا الخاصة التي ستتصرف كما أردنا ، من المفترض أن تكون شيئًا مثل هذا:

كما يمكنك التخمين ، يتم نسخ هذه الشفرة والطرق المساعدة بوحشية ، مع بعض التبسيط ، من شفرة مصدر ViewGroup (لماذا لا تكون محمية يا عزيزي مطوري Android؟!).

والنتيجة:

ملاحظة تم نشر هذه المقالة في الأصل على مدونتي.