ความหมายของค่าบูลีนที่ส่งคืนจากวิธีการจัดการเหตุการณ์ใน Android คืออะไร


110

ใน Android วิธีการฟังเหตุการณ์ส่วนใหญ่จะส่งคืนค่าบูลีน ค่าจริง / เท็จนั้นหมายถึงอะไร? เหตุการณ์ต่อมาจะเป็นอย่างไร

class MyTouchListener implements OnTouchListener {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        logView.showEvent(event);
        return true;
    }
}

เกี่ยวกับตัวอย่างข้างต้นถ้าผลตอบแทนจริงในonTouchวิธีผมพบว่าทุกเหตุการณ์ touch (ลง, ขึ้น, ย้าย, ฯลฯ ) ได้รับการบันทึกตามฉันlogview ในทางตรงกันข้ามหากส่งคืนเป็นเท็จเหตุการณ์ DOWN ถูกจับเท่านั้น ดูเหมือนว่าการส่งคืนเท็จจะป้องกันไม่ให้เหตุการณ์แพร่กระจาย ฉันถูกไหม ?

นอกจากนี้ในOnGestureListenerหลายวิธีต้องคืนค่าบูลีนด้วย มีความหมายเดียวกันหรือไม่?

คำตอบ:


140

หากคุณกลับtrueจากACTION_DOWNกิจกรรมคุณสนใจกิจกรรมที่เหลือในท่าทางนั้น A "ท่าทาง" ในกรณีนี้หมายถึงเหตุการณ์ที่เกิดขึ้นทั้งหมดจนกว่าสุดท้ายหรือACTION_UP ACTION_CANCELการกลับมาfalseจากACTION_DOWNวิธีการที่คุณไม่ต้องการให้เหตุการณ์และมุมมองอื่น ๆ มีโอกาสที่จะจัดการกับมัน หากคุณมีมุมมองที่ทับซ้อนกันสิ่งนี้อาจเป็นมุมมองพี่น้อง ถ้าไม่เป็นฟองจะขึ้นอยู่กับผู้ปกครอง


3
adamp มีวิธีรับเหตุการณ์ต่อไปและปล่อยให้เหตุการณ์ผ่านไปหรือไม่?
ticofab

@ticofab ไม่เฉพาะผู้ปกครองของข้อมูลพร็อพเพอร์ตี้ที่รับเหตุการณ์ในปัจจุบันเท่านั้นที่สามารถสกัดกั้นเหตุการณ์ในอนาคตได้ในท่าทางสัมผัส (แน่นอนคุณสามารถสร้างระบบเปลี่ยนเส้นทางของคุณเองในมุมมองผู้ปกครองได้ตลอดเวลา แต่ฉันจะไม่แนะนำให้ทำเว้นแต่คุณจะรู้ว่าคุณกำลังทำอะไรอยู่ :))
adamp

@adamp ฉันนึกไม่ออกว่าทำไม onTouch ถึงเรียก 2 ครั้งเมื่อคืนค่าจริงและ 1 ครั้งก็ต่อเมื่อฉันส่งคืนเท็จ
Bhargav Jhaveri

1
@adamp: ฉันส่งคืนเท็จจาก ACTION_DOWN แต่ ACTION_UP ของฉันถูกทริกเกอร์และดำเนินการ
Mahantesh M Ambi

ฉันได้รับคำตอบนี้ผิดหรือคนอื่นคือ ... คำตอบนี้บอกว่ากลับจริงหมายความว่าเหตุการณ์ที่ยากจะไม่ถูกใช้ แต่ความจริงกลับตรงกันข้ามอย่างสิ้นเชิง
ไก่วัง

23

จากเอกสารประกอบ: http://developer.android.com/reference/android/view/View OnTouchListener.html # onTouch (android.view.View, android.view.MotionEvent)

"จริงถ้าผู้ฟังบริโภคเหตุการณ์เป็นอย่างอื่นเท็จ"

หากคุณส่งคืนจริงเหตุการณ์จะถูกประมวลผล ถ้าเป็นเท็จมันจะไปที่เลเยอร์ถัดไปด้านล่าง


12

ค่าบูลีนเป็นตัวกำหนดว่าเหตุการณ์ถูกใช้ไปหรือไม่

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


2
นี่เป็นเท็จ trueหมายความว่าคุณใช้งานกิจกรรมและต้องการให้กิจกรรมที่เหลืออยู่ในท่าทางสัมผัส - ผู้ฟัง / มุมมองอื่น ๆ จะไม่ได้รับกิจกรรม falseหมายถึงให้คนอื่นจัดการเหตุการณ์ จริงๆแล้วมันเจาะจงกว่านั้นเล็กน้อย ดูคำตอบของฉัน
adamp

มันไม่ตรงตามที่พูดไว้ได้อย่างไร?
Falmarri

1
สิ่งที่คุณพูดกลับตรงกันข้าม :)
adamp

4

คำตอบทั้งหมดข้างต้นถูกต้อง แต่ผลลัพธ์จะแตกต่างกันคือหาก View เป็นclickableหรือไม่clickable

ตัวอย่างฉันLinearLayoutมี 1 Buttonและ 1 TextViewแบบนี้

<LinearLayout
    android:id="@+id/linearlayout_root"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0aa"
    android:orientation="vertical">

    <Button
        android:id="@+id/button_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="40dp"
        android:text="Button Click"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/textview_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="40dp"
        android:text="TextView Click"
        android:textSize="20sp"
        android:background="#e4e4e4"
        />

</LinearLayout>

ในกิจกรรมฉันมีรหัสเช่น

class MainActivity : AppCompatActivity() {
    val TAG = "TAG"

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<LinearLayout>(R.id.linearlayout_root).setOnTouchListener { v, event ->
            Log.i(TAG, "LinearLayout onTouch event " + getDisplayAction(event.action))
            false
        }

        findViewById<Button>(R.id.button_click).setOnTouchListener { v, event ->
            Log.i(TAG, "Button onTouch event " + getDisplayAction(event.action))
            false
        }

        findViewById<TextView>(R.id.textview_click).setOnTouchListener { v, event ->
            Log.i(TAG, "TextView onTouch event " + getDisplayAction(event.action))
            false
        }
    }

    private fun getDisplayAction(action: Int): String {
        return when (action) {
            MotionEvent.ACTION_DOWN -> "DOWN"
            MotionEvent.ACTION_MOVE -> "MOVE"
            MotionEvent.ACTION_UP -> "UP"
            MotionEvent.ACTION_CANCEL -> "CANCEL"
            MotionEvent.ACTION_OUTSIDE -> "OUTSIDE"
            else -> "UNKNOWN"
        }
    }
}

กรณีที่ 1 Linear onTouch return **FALSE**, Button onTouch return **FALSE**,TextView onTouch return **FALSE**

คลิกที่ปุ่ม

I/TAG: Button onTouch eventDOWN
I/TAG: Button onTouch eventMOVE
I/TAG: Button onTouch eventUP

คลิกที่ TextView

TAG: TextView onTouch eventDOWN
TAG: LinearLayout onTouch eventDOWN

คลิกที่ LinearLayout

TAG: LinearLayout onTouch eventDOWN

กรณีที่ 2 Linear onTouch return **FALSE**, Button onTouch return **TRUE**,TextView onTouch return **TRUE**

คลิกที่ปุ่ม

Similar to case 1

คลิกที่ TextView

TAG: TextView onTouch event DOWN
TAG: TextView onTouch event MOVE
TAG: TextView onTouch event UP

คลิกที่ LinearLayout

Similar to case 1

กรณีที่ 3 Linear onTouch return **TRUE**, Button onTouch return **FALSE**,TextView onTouch return **FALSE**

คลิกที่ปุ่ม

Similar to case 1

คลิกที่ TextView

TAG: TextView onTouch event DOWN
TAG: LinearLayout onTouch event DOWN
TAG: LinearLayout onTouch event MOVE
TAG: LinearLayout onTouch event UP

คลิกที่ LinearLayout

TAG: LinearLayout onTouch event DOWN
TAG: LinearLayout onTouch event MOVE
TAG: LinearLayout onTouch event UP

บันทึก

  • ค่าเริ่มต้นของTextViewคือnot clickableจะกลายเป็นคลิกได้หากเราตั้งค่าเป็นandroid:clickable="true"xml หรือเมื่อเราตั้งค่าtextView.setOnClickListener(...)
  • เมื่อคุณแก้ไขข้อบกพร่องevent MOVEสามารถโทรได้มากกว่าบันทึกของฉัน (ขึ้นอยู่กับวิธีที่คุณแตะ)

สรุป

  • onTouchreturn trueหรือ view is clickable , View จะได้รับทั้งหมด onTouchEvent
  • onTouchreturn falseand view is not clickable, view จะไม่ได้รับ NEXT onTouchEvent (ซึ่งเป็นผู้ปกครองอาจได้รับ)

หวังว่าจะช่วย
DEMO


1
นี่น่าจะเป็นคำตอบ! ขอบคุณสำหรับคำอธิบายโดยละเอียด
Mysterious_android

1

ฉันเสียเวลาเกือบหนึ่งวันในการแก้ไขปัญหา แต่ฉันยังพบว่าฟังก์ชัน onTouch ของฉันถูกเรียก 2 ครั้งเมื่อใช้ true และ 1 ครั้งเมื่อใช้ false


คุณหาเหตุผลได้ไหม
Bhargav Jhaveri

ตรวจสอบevent.getAction()เพราะถ้าคุณกลับมาfalseในกิจกรรม ACTION_DOWN ผู้ฟังจะไม่สนใจเหตุการณ์
ACTION_UP

0

จากเอกสาร Android :

หมายเหตุ: Android จะเรียกตัวจัดการเหตุการณ์ก่อนจากนั้นตัวจัดการเริ่มต้นที่เหมาะสมจากนิยามคลาสที่สอง ดังนั้นการส่งคืนจริงจากผู้ฟังเหตุการณ์เหล่านี้จะหยุดการเผยแพร่เหตุการณ์ไปยังผู้ฟังเหตุการณ์อื่น ๆ และจะบล็อกการเรียกกลับไปยังตัวจัดการเหตุการณ์เริ่มต้นในมุมมองด้วย ดังนั้นโปรดแน่ใจว่าคุณต้องการยุติเหตุการณ์เมื่อคุณส่งคืนจริง

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