Android: ความแตกต่างระหว่าง onTceptTouchEvent และ dispatchTouchEvent หรือไม่


249

ความแตกต่างระหว่างonInterceptTouchEventและdispatchTouchEventใน Android คืออะไร?

ตามคู่มือผู้พัฒนา android ทั้งสองวิธีสามารถใช้เพื่อสกัดเหตุการณ์การสัมผัส ( MotionEvent) แต่ความแตกต่างคืออะไร

วิธีทำonInterceptTouchEvent, dispatchTouchEventและonTouchEventโต้ตอบกันอยู่ในลำดับชั้นของผู้ชม (กViewGroup)?

คำตอบ:


272

ที่ดีที่สุดในการ demystify นี้เป็นรหัสที่มา เอกสารไม่เพียงพออย่างมากเกี่ยวกับการอธิบายเรื่องนี้

dispatchTouchEvent มีการกำหนดจริงในกิจกรรมดูและดูกลุ่ม คิดว่ามันเป็นตัวควบคุมที่ตัดสินใจว่าจะกำหนดเส้นทางเหตุการณ์สัมผัส

ตัวอย่างเช่นกรณีที่ง่ายที่สุดคือการView.dispatchTouchEventซึ่งจะเส้นทางเหตุการณ์สัมผัสทั้งOnTouchListener.onTouchถ้ามันกำหนดไว้หรือวิธีการขยายonTouchEvent

สำหรับสิ่งที่ViewGroup.dispatchTouchEventมีความซับซ้อนมากขึ้น จำเป็นต้องทราบว่าหนึ่งในมุมมองลูกของมันควรได้รับเหตุการณ์ (โดยการเรียก child.dispatchTouchEvent) นี่เป็นอัลกอริธึมการทดสอบการเข้าชมที่คุณคิดออกว่าขอบเขตการโยงของมุมมองลูกใดที่มีพิกัดจุดสัมผัส

แต่ก่อนที่จะสามารถส่งเหตุการณ์ไปยังมุมมองลูกที่เหมาะสมผู้ปกครองสามารถสอดแนมและ / หรือขัดขวางเหตุการณ์ทั้งหมดเข้าด้วยกัน นี่คือสิ่งที่onInterceptTouchEventจะมีสำหรับ ดังนั้นจึงเรียกวิธีนี้ก่อนที่จะทำการทดสอบการตีและหากเหตุการณ์ถูกจี้ (โดยการคืนค่าจริงจาก onInterceptTouchEvent) มันจะส่งACTION_CANCELไปยังมุมมองลูกเพื่อให้พวกเขาสามารถละทิ้งการประมวลผลกิจกรรมการสัมผัส (จากกิจกรรมการสัมผัสก่อนหน้านี้) กิจกรรมการสัมผัสทั้งหมดที่ระดับผู้ปกครองจะถูกส่งไปยังonTouchListener.onTouch (ถ้ากำหนดไว้) หรือonTouchEvent () นอกจากนี้ในกรณีนั้น onInterceptTouchEvent จะไม่ถูกเรียกอีกครั้ง

คุณต้องการแทนที่ [กิจกรรม | ViewGroup | View] .dispatchTouchEvent หรือไม่ หากคุณไม่ได้กำหนดเส้นทางเองคุณอาจไม่ควรทำ

วิธีการขยายหลักคือ ViewGroup.onInterceptTouchEvent หากคุณต้องการสอดแนมและ / หรือดักจับเหตุการณ์การสัมผัสที่ระดับผู้ปกครองและ View.onTouchListener / View.onTouchEvent สำหรับการจัดการเหตุการณ์หลัก

ทั้งหมดในทุกการออกแบบที่ซับซ้อนมากเกินไป imo แต่ Android apis พึ่งพาความยืดหยุ่นมากกว่าความเรียบง่าย


10
นี่เป็นคำตอบที่ดีและกระชับ สำหรับรายละเอียดเพิ่มเติมดูการฝึกอบรม"การจัดการกิจกรรมการสัมผัสใน ViewGroup"
TalkLittle

1
@numan salati: "นับจากนั้นเป็นต้นมากิจกรรมการสัมผัสทั้งหมดในระดับผู้ปกครองจะถูกส่งไปยัง onTouchListener.onTouch" - ฉันต้องการแทนที่วิธีการเลือกส่งในกลุ่มมุมมองของฉันและทำให้มันส่งกิจกรรมไปที่ onTouchListener แต่ฉันไม่เห็นว่ามันสามารถทำได้ ไม่มี API สำหรับสิ่งนั้นเช่น View.getOnTouchListener (). onTouch () มีเมธอด setOnTouchListener () แต่ไม่มีเมธอด getOnTouchListener () จะทำอย่างไรได้บ้าง?
Ashwin

@ แสดงความคิดเห็นของฉันอย่างแน่นอนไม่มีการตั้งค่าไว้ที่ InceptceptTouchEvent คุณสามารถแทนที่มุมมองคลาสย่อยเพื่อใช้ในเลย์เอาต์ / เพิ่มในโค้ด แต่คุณไม่สามารถยุ่งกับ rootViews ส่วน / กิจกรรมระดับเนื่องจากคุณไม่สามารถ subclass มุมมองเหล่านั้นโดยไม่ต้อง subclassing ชิ้นส่วน / กิจกรรมเอง (เช่นในความเข้ากันได้มากที่สุด การใช้งาน ProgressActivitiy) API ต้องการ setOnInterceptTouchEvent เพื่อความเรียบง่าย ทุกคนใช้ interceptTouch บน rootViews ในบางจุดในแอพแบบกึ่งซับซ้อน
leRobot

244

เพราะนี่เป็นผลลัพธ์แรกของ Google ฉันต้องการที่จะร่วมกับคุณพูดคุยที่ดีโดยเดฟสมิ ธ ในyoutube: นาย Android ระบบสัมผัสและภาพนิ่งมีอยู่ที่นี่ มันทำให้ฉันมีความเข้าใจอย่างลึกซึ้งเกี่ยวกับระบบสัมผัส Android:

วิธีกิจกรรมจับสัมผัส:

  • Activity.dispatchTouchEvent()
    • ก่อนที่จะถูกเรียกเสมอ
    • ส่งเหตุการณ์ไปยังมุมมองรูทที่แนบกับหน้าต่าง
    • onTouchEvent()
      • เรียกว่าถ้าไม่มีมุมมองใช้เหตุการณ์
      • มีอายุการใช้งานยาวนาน

วิธีการที่Viewจัดการกับการสัมผัส:

  • View.dispatchTouchEvent()
    • ส่งเหตุการณ์ไปยังผู้ฟังก่อนถ้ามี
      • View.OnTouchListener.onTouch()
    • หากไม่บริโภคให้ประมวลผลการสัมผัส
      • View.onTouchEvent()

วิธีViewGroupจับสัมผัส:

  • ViewGroup.dispatchTouchEvent()
    • onInterceptTouchEvent()
      • ตรวจสอบว่าควรแทนที่เด็ก
      • ส่งผ่าน ACTION_CANCEL ไปยังเด็กที่ใช้งานอยู่
      • ถ้ามันคืนค่าจริงหนึ่งครั้งViewGroupเหตุการณ์นั้นจะใช้เหตุการณ์ที่ตามมาทั้งหมด
    • สำหรับมุมมองเด็กแต่ละคน (ในลำดับที่กลับกันพวกเขาจะถูกเพิ่ม)
      • หากการสัมผัสมีความเกี่ยวข้อง (ภายในมุมมอง) child.dispatchTouchEvent()
      • ถ้ามันไม่ได้ถูกจัดการโดยก่อนหน้านี้ส่งไปที่มุมมองถัดไป
    • หากไม่มีเด็กจัดการเหตุการณ์ผู้ฟังจะได้รับโอกาส
      • OnTouchListener.onTouch()
    • หากไม่มีผู้ฟังหรือไม่มีการจัดการ
      • onTouchEvent()
  • เหตุการณ์ที่ถูกดักกระโดดข้ามขั้นตอนลูก

นอกจากนี้เขายังให้โค้ดตัวอย่างของการสัมผัสที่กำหนดเองในgithub.com/devunwired/

คำตอบ: โดยทั่วไปแล้วdispatchTouchEvent()จะถูกเรียกบนทุกViewเลเยอร์เพื่อตรวจสอบว่า a Viewมีความสนใจในท่าทางที่กำลังดำเนินอยู่หรือไม่ ในการViewGroupที่ViewGroupมีความสามารถในการขโมยกิจกรรมการสัมผัสในวิธีการของเขาdispatchTouchEvent()ก่อนที่มันจะเรียกร้องdispatchTouchEvent()ให้เด็ก ๆ ViewGroupเท่านั้นที่จะหยุดเยี่ยงอย่างถ้าViewGroup onInterceptTouchEvent()ผลตอบแทน -method จริง ความแตกต่างก็คือว่าdispatchTouchEvent()เป็นเยี่ยงอย่างMotionEventsและonInterceptTouchEventบอกว่าถ้ามันจะสกัดกั้น(ไม่เยี่ยงอย่างMotionEventให้กับเด็ก ๆ )หรือไม่(เยี่ยงอย่างให้กับเด็ก)

คุณสามารถจินตนาการถึงรหัสของ ViewGroup ที่ทำสิ่งนี้มากหรือน้อย (ง่ายมาก):

public boolean dispatchTouchEvent(MotionEvent ev) {
    if(!onInterceptTouchEvent()){
        for(View child : children){
            if(child.dispatchTouchEvent(ev))
                return true;
        }
    }
    return super.dispatchTouchEvent(ev);
}

64

คำตอบเพิ่มเติม

ต่อไปนี้เป็นข้อมูลเพิ่มเติมเกี่ยวกับภาพสำหรับคำตอบอื่น ๆ คำตอบทั้งหมดของฉันคือที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

dispatchTouchEvent()วิธีการของViewGroupการใช้งานonInterceptTouchEvent()ให้เลือกไม่ว่าจะควรจะจัดการทันทีเหตุการณ์สัมผัส (กับonTouchEvent()) หรือยังคงแจ้งdispatchTouchEvent()วิธีการของเด็ก


ใน InterceptTouchEvent สามารถเรียกใช้ด้วยในกิจกรรมได้หรือไม่? ฉันคิดว่าเป็นไปได้เฉพาะใน ViewGroup หรือฉันผิด @Suragch
Federico Rizzo

@FedericoRizzo คุณพูดถูก! ขอบคุณมาก! ฉันอัพเดตไดอะแกรมและคำตอบแล้ว
Suragch

20

มีความสับสนมากมายเกี่ยวกับวิธีการเหล่านี้ แต่จริงๆแล้วมันไม่ซับซ้อน ความสับสนส่วนใหญ่เป็นเพราะ:

  1. หากคุณView/ViewGroupหรือใด ๆ ของเด็กไม่ได้กลับจริงใน onTouchEvent, dispatchTouchEventและจะได้รับการเรียกร้องให้onInterceptTouchEvent MotionEvent.ACTION_DOWNโดยไม่ต้องมีความจริงจาก onTouchEventมุมมองของผู้ปกครองจะถือว่ามุมมองของคุณไม่จำเป็นต้อง MotionEvents
  2. เมื่อไม่มีเด็กของ ViewGroup กลับจริงใน onTouchEvent, onInterceptTouchEvent จะถูกเรียกว่าMotionEvent.ACTION_DOWNแม้ว่า ViewGroup onTouchEventของคุณกลับมาจริง

ลำดับการประมวลผลเป็นดังนี้:

  1. dispatchTouchEvent ถูกเรียก.
  2. onInterceptTouchEventจะเรียกMotionEvent.ACTION_DOWNหรือเมื่อใด ๆ ของเด็กของ ViewGroup onTouchEventกลับในความจริง
  3. onTouchEventเป็นครั้งแรกที่เรียกว่าเด็กของ ViewGroup View/ViewGroupและเมื่อไม่มีเด็กกลับจริงมันถูกเรียกบนที่

หากคุณต้องการดูตัวอย่างTouchEvents/MotionEventsโดยไม่ปิดใช้งานกิจกรรมในลูก ๆ ของคุณคุณต้องทำสองสิ่ง:

  1. แทนที่dispatchTouchEventเพื่อดูตัวอย่างเหตุการณ์และกลับมา super.dispatchTouchEvent(ev);
  2. แทนที่onTouchEventและกลับจริงมิฉะนั้นคุณจะไม่ได้รับใด ๆ ยกเว้นMotionEvent MotionEvent.ACTION_DOWN

หากคุณต้องการตรวจจับท่าทางบางอย่างเช่นเหตุการณ์ปัดโดยไม่ต้องปิดใช้งานกิจกรรมอื่น ๆ บนลูก ๆ ของคุณตราบใดที่คุณไม่ได้ตรวจจับท่าทางคุณสามารถทำสิ่งนี้ได้:

  1. ดูตัวอย่าง MotionEvents ตามที่อธิบายไว้ข้างต้นและตั้งค่าสถานะเมื่อคุณตรวจพบท่าทางของคุณ
  2. กลับมาจริงonInterceptTouchEventเมื่อตั้งค่าสถานะเป็นยกเลิกการประมวลผล MotionEvent โดยลูก ๆ ของคุณ นอกจากนี้ยังเป็นสถานที่ที่สะดวกในการตั้งค่าธงของคุณเพราะ onInterceptTouchEvent MotionEvent.ACTION_DOWNจะไม่ถูกเรียกอีกครั้งจนกว่าถัดไป

ตัวอย่างการแทนที่ในFrameLayout(ตัวอย่างของฉันคือ C # ขณะที่ฉันกำลังเขียนโปรแกรมกับ Xamarin Android แต่ตรรกะนั้นเหมือนกันใน Java):

public override bool DispatchTouchEvent(MotionEvent e)
{
    // Preview the touch event to detect a swipe:
    switch (e.ActionMasked)
    {
        case MotionEventActions.Down:
            _processingSwipe = false;
            _touchStartPosition = e.RawX;
            break;
        case MotionEventActions.Move:
            if (!_processingSwipe)
            {
                float move = e.RawX - _touchStartPosition;
                if (move >= _swipeSize)
                {
                    _processingSwipe = true;
                    _cancelChildren = true;
                    ProcessSwipe();
                }
            }
            break;
    }
    return base.DispatchTouchEvent(e);
}

public override bool OnTouchEvent(MotionEvent e)
{
    // To make sure to receive touch events, tell parent we are handling them:
    return true;
}

public override bool OnInterceptTouchEvent(MotionEvent e)
{
    // Cancel all children when processing a swipe:
    if (_cancelChildren)
    {
        // Reset cancel flag here, as OnInterceptTouchEvent won't be called until the next MotionEventActions.Down:
        _cancelChildren = false;
        return true;
    }
    return false;
}

3
ฉันไม่รู้ว่าทำไมมันถึงไม่มี upvotes มากกว่านี้ มันเป็นคำตอบที่ดี (IMO) และฉันคิดว่ามันมีประโยชน์มาก
Mark Ormesher

8

ฉันมาข้ามคำอธิบายที่ง่ายมากที่หน้าเว็บนี้http://doandroids.com/blogs/tag/codeexample/ นำมาจากที่นั่น:

  • บูลีน onTouchEvent (MotionEvent ev) - เรียกว่าเมื่อใดก็ตามที่เหตุการณ์การสัมผัสด้วยมุมมองนี้เป็นที่ตรวจพบเป้าหมาย
  • บูลีน onInterceptTouchEvent (MotionEvent ev) - เรียกเมื่อใดก็ตามที่ตรวจพบเหตุการณ์การสัมผัสด้วย ViewGroup นี้หรือลูก ๆ ของมันเป็นเป้าหมาย หากฟังก์ชั่นนี้คืนค่าเป็นจริง MotionEvent จะถูกดักซึ่งหมายความว่ามันจะไม่ถูกส่งต่อไปยังเด็ก แต่จะไปที่ onTouchEvent ของมุมมองนี้

2
คำถามเกี่ยวกับ onterceptTouchEvent และ dispatchTouchEvent ทั้งคู่เป็นสายก่อน onTouchEvent แต่ในตัวอย่างนั้นคุณไม่เห็น dispatchTouchEvent
Dayerman

8

dispatchTouchEvent จัดการก่อนบนInterceptTouchEvent

ใช้ตัวอย่างง่ายๆนี้:

   main = new LinearLayout(this){
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            System.out.println("Event - onInterceptTouchEvent");
            return super.onInterceptTouchEvent(ev);
            //return false; //event get propagated
        }
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            System.out.println("Event - dispatchTouchEvent");
            return super.dispatchTouchEvent(ev);
            //return false; //event DONT get propagated
        }
    };

    main.setBackgroundColor(Color.GRAY);
    main.setLayoutParams(new LinearLayout.LayoutParams(320,480));    


    viewA = new EditText(this);
    viewA.setBackgroundColor(Color.YELLOW);
    viewA.setTextColor(Color.BLACK);
    viewA.setTextSize(16);
    viewA.setLayoutParams(new LinearLayout.LayoutParams(320,80));
    main.addView(viewA);

    setContentView(main);

คุณจะเห็นว่าบันทึกจะเป็นดังนี้:

I/System.out(25900): Event - dispatchTouchEvent
I/System.out(25900): Event - onInterceptTouchEvent

ดังนั้นในกรณีที่คุณทำงานกับตัวจัดการ 2 ตัวนี้ให้ใช้ dispatchTouchEvent เพื่อจัดการกับเหตุการณ์แรกซึ่งจะไปที่InterceptTouchEvent

ความแตกต่างอีกอย่างก็คือถ้า dispatchTouchEvent ส่งคืน 'false' เหตุการณ์จะไม่ถูกส่งไปยังเด็กในกรณีนี้ EditText ในขณะที่ถ้าคุณส่งคืน false ใน onInterceptTouchEvent เหตุการณ์จะยังคงถูกส่งไปยัง EditText


5

คำตอบสั้น ๆ : dispatchTouchEvent()จะถูกเรียกครั้งแรกของทั้งหมด

คำแนะนำสั้น ๆ :ไม่ควรลบล้างdispatchTouchEvent()เนื่องจากควบคุมได้ยากบางครั้งอาจทำให้ประสิทธิภาพของคุณช้าลง IMHO onInterceptTouchEvent()ผมขอแนะนำให้เอาชนะ


เนื่องจากคำตอบส่วนใหญ่พูดถึงอย่างชัดเจนเกี่ยวกับเหตุการณ์โฟลว์ทัชบนกิจกรรม / มุมมองกลุ่ม / มุมมองฉันเพียงเพิ่มรายละเอียดเพิ่มเติมเกี่ยวกับโค้ดเกี่ยวกับวิธีการเหล่านี้ในViewGroup(ไม่สนใจdispatchTouchEvent()):

onInterceptTouchEvent()จะถูกเรียกก่อนเหตุการณ์ ACTION จะถูกเรียกตามลำดับ down -> move -> up มี 2 ​​กรณี:

  1. ถ้าคุณกลับเท็จใน 3 กรณี (ACTION_DOWN, ACTION_MOVE, ACTION_UP) ก็จะพิจารณาเป็นพ่อแม่จะไม่จำเป็นต้องสัมผัสเหตุการณ์นี้ดังนั้นonTouch()พ่อแม่ไม่เคยเรียกแต่onTouch()เด็กจะเรียกแทน ; อย่างไรก็ตามโปรดแจ้งให้ทราบ:

    • ยังคงได้รับการจัดกิจกรรมสัมผัสตราบใดที่เด็กไม่ได้โทรonInterceptTouchEvent()requestDisallowInterceptTouchEvent(true)
    • หากไม่มีเด็กที่ได้รับเหตุการณ์นั้น (สามารถเกิดขึ้นได้ใน 2 กรณี: ไม่มีเด็กในตำแหน่งที่ผู้ใช้สัมผัสหรือมีลูก แต่กลับเป็นเท็จที่ ACTION_DOWN) ผู้ปกครองจะส่งเหตุการณ์นั้นกลับไปonTouch()ยังผู้ปกครอง
  2. ในทางกลับกันถ้าคุณกลับจริงที่ผู้ปกครองจะขโมยเหตุการณ์สัมผัสนี้ทันทีและonInterceptTouchEvent()จะหยุดทันทีแทนonTouch()ของพ่อแม่จะถูกเรียกว่าเช่นเดียวกับonTouch()เด็กจะได้รับเหตุการณ์การกระทำที่ผ่านมา - ACTION_CANCEL (ดังนั้นมันหมายถึงพ่อแม่ ขโมยกิจกรรมการสัมผัสและเด็กไม่สามารถจัดการได้ตั้งแต่นั้นมา) การไหลเวียนของonInterceptTouchEvent()ผลตอบแทนที่ผิดปกติเป็นเรื่องปกติ แต่มีความสับสนเล็กน้อยกับกรณีที่เกิดขึ้นจริงดังนั้นฉันจึงแสดงไว้ที่นี่:

    • ส่งคืนจริงที่ ACTION_DOWN onTouch()ของผู้ปกครองจะได้รับ ACTION_DOWN อีกครั้งและดำเนินการตาม (ACTION_MOVE, ACTION_UP)
    • ส่งคืนจริงที่ ACTION_MOVE onTouch()ของผู้ปกครองจะได้รับACTION_MOVE ถัดไป (ไม่ใช่ ACTION_MOVE เดียวกันonInterceptTouchEvent()) และการกระทำต่อไปนี้ (ACTION_MOVE, ACTION_UP)
    • ส่งคืนจริงที่ ACTION_UP onTouch()ของผู้ปกครองจะไม่ถูกเรียกเลยเพราะมันสายเกินไปที่ผู้ปกครองจะขโมยกิจกรรมการสัมผัส

สิ่งสำคัญอีกอย่างหนึ่งคือ ACTION_DOWN ของกิจกรรมในonTouch()จะพิจารณาว่ามุมมองต้องการรับการดำเนินการเพิ่มเติมจากเหตุการณ์นั้นหรือไม่ หากมุมมองกลับคืนจริงเมื่อ ACTION_DOWN onTouch()หมายถึงมุมมองนั้นยินดีรับการดำเนินการเพิ่มเติมจากเหตุการณ์นั้น มิฉะนั้นส่งคืน false ที่ ACTION_DOWN ในซึ่งonTouch()บ่งบอกว่ามุมมองจะไม่ได้รับการดำเนินการใด ๆ จากกิจกรรมนั้นอีก


4

คุณสามารถหาคำตอบได้ในวิดีโอนี้https://www.youtube.com/watch?v=SYoN-OvdZ3M&list=PLonJJ3BVjZW6CtAMbJz1XD8ELUs1KXaTD&index=19และวิดีโอ 3 รายการถัดไป กิจกรรมการสัมผัสทั้งหมดได้รับการอธิบายได้ดีมากมันชัดเจนและเต็มไปด้วยตัวอย่าง


นี่เป็นวิดีโอที่ดีจริงๆฉันดูไปสองสามครั้งแล้วก็แก้ปัญหาของฉันได้
Simon

3

รหัสต่อไปนี้ภายในคลาสย่อย ViewGroup จะป้องกันไม่ให้มันเป็นภาชนะหลักที่ได้รับเหตุการณ์สัมผัส:

  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    // Normal event dispatch to this container's children, ignore the return value
    super.dispatchTouchEvent(ev);

    // Always consume the event so it is not dispatched further up the chain
    return true;
  }

ฉันใช้สิ่งนี้กับการซ้อนทับที่กำหนดเองเพื่อป้องกันไม่ให้มุมมองพื้นหลังตอบสนองต่อการสัมผัสเหตุการณ์


1

ความแตกต่างหลัก:

• Activity.dispatchTouchEvent (MotionEvent) - สิ่งนี้จะช่วยให้กิจกรรมของคุณสกัดกั้นเหตุการณ์การสัมผัสทั้งหมดก่อนที่จะถูกส่งไปที่หน้าต่าง
• ViewGroup.onInterceptTouchEvent (MotionEvent) - สิ่งนี้จะช่วยให้ ViewGroup ดูเหตุการณ์ที่เกิดขึ้นเมื่อถูกส่งไปยังมุมมองเด็ก


1
ใช่ฉันรู้คำตอบนี้จากคู่มือผู้พัฒนาระบบ Android - ยังไม่ชัดเจน วิธีการ dispatchTouchEvent ยังมีอยู่สำหรับ ViewGroup ไม่เพียง แต่สำหรับกิจกรรม คำถามของฉันคือวิธีที่สามวิธีในการส่งผ่าน TouchEvent, onInceptceptTouchEvent และ onTouchEvent ทำงานร่วมกันภายในลำดับชั้นของ ViewGroups เช่น RelativeLayouts
แอนน์ Droid

1

ViewGroup's onInterceptTouchEvent()เป็นจุดเริ่มต้นสำหรับACTION_DOWNเหตุการณ์ที่เกิดขึ้นเป็นครั้งแรกเสมอ

หากคุณต้องการที่จะดำเนินการ ViewGroup onInterceptTouchEvent()ท่าทางนี้กลับจริงจาก เมื่อส่งคืนจริง ViewGroup onTouchEvent()จะได้รับเหตุการณ์ที่ตามมาทั้งหมดจนถึงเหตุการณ์ถัดไปACTION_UPหรือACTION_CANCELในกรณีส่วนใหญ่เหตุการณ์การสัมผัสระหว่างACTION_DOWNและACTION_UPหรือACTION_CANCELเป็นACTION_MOVEซึ่งโดยทั่วไปจะรับรู้ว่าเป็นท่าทางการเลื่อน / พุ่ง

หากคุณกลับเท็จจากonInterceptTouchEvent()มุมมองเป้าหมายonTouchEvent()จะถูกเรียก onInterceptTouchEvent()มันจะต้องทำซ้ำสำหรับข้อความที่ตามมาจนกว่าคุณจะกลับจริงจาก

ที่มา: http://neevek.net/posts/2013/10/13/implementing-onInterceptTouchEvent-and-onTouchEvent-for-ViewGroup.html


0

ทั้งกิจกรรมและมุมมองมีเมธอด dispatchTouchEvent () และ onTouchEvent ViewGroup มีวิธีนี้เช่นกัน แต่มีวิธีอื่นที่เรียกว่า onInterceptTouchEvent ชนิดที่ส่งคืนของเมธอดเหล่านั้นคือบูลีนคุณสามารถควบคุมเส้นทางการจัดส่งผ่านค่าส่งคืน

การจัดส่งกิจกรรมใน Android เริ่มต้นจากกิจกรรม -> ViewGroup-> มุมมอง


0
public boolean dispatchTouchEvent(MotionEvent ev){
    boolean consume =false;
    if(onInterceptTouchEvent(ev){
        consume = onTouchEvent(ev);
    }else{
        consume = child.dispatchTouchEvent(ev);
    }
}

1
คุณสามารถเพิ่มคำอธิบายได้ไหม?
พอลฟลอยด์

3
ในขณะที่ข้อมูลโค้ดนี้อาจแก้ปัญหาได้รวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
Rosário Pereira Fernandes

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.