Android'de bir olay işleme yönteminden döndürülen boole değerinin anlamı nedir?


110

Android'de çoğu olay dinleyici yöntemi bir boole değeri döndürür. Bu doğru / yanlış değer ne anlama geliyor? alt sıradaki olaylara ne yol açacak?

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

Yukarıdaki örnekle ilgili olarak, onTouch yönteminde true döndürürseniz , her dokunma olayının (DOWN, UP, MOVE, vb.) LogView'uma göre yakalandığını buldum . Aksine, yanlış döndürürse, yalnızca DOWN olayı yakalanır. Öyleyse, yanlış dönüşün olayın yayılmasını önleyeceği görülüyor. Doğrumuyum ?

Ayrıca, bir OnGestureListener'da birçok yöntemin de bir boole değeri döndürmesi gerekir. Aynı anlama mı sahipler?

Yanıtlar:


140

Bir olaydan dönerseniz true, ACTION_DOWNo hareketteki olayların geri kalanıyla ilgilenirsiniz. Bu durumda bir "hareket", final ACTION_UPveya ACTION_CANCEL. falseBir ACTION_DOWNolayı istemediğiniz bir yoldan dönmek ve diğer görünümler bunu halletme fırsatına sahip olacaktır. Örtüşen görünümleriniz varsa, bu bir kardeş görünümü olabilir. Değilse, ebeveyne dönüşecek.


3
adamp, olayları almaya devam etmenin VE olayların geçmesine izin vermenin bir yolu var mı?
ticofab

@ticofab hayır, yalnızca şu anda olayları alan görünümün bir üst öğesi harekette gelecekteki olayları yakalayabilir. (Elbette, bir ebeveyn görünümünde her zaman kendi yönlendirme sistemlerinizi oluşturabilirsiniz, ancak ne yaptığınızı gerçekten bilmiyorsanız bunu tavsiye etmem. :))
adamp

@adamp onTouch'ın true dönerken 2 kez ve yalnızca false döndürdüğümde 1 kez çağrılmasının nedenini düşünemiyorum.
Bhargav Jhaveri

1
@adamp: ACTION_DOWN'dan yanlış döndürüyorum ama ACTION_UP'ım tetikleniyor ve yürütülüyor.
Mahantesh M Ambi

Bu cevabı yanlış mı alıyorum yoksa diğer herkes ... Bu cevap, gerçeğe dönüşün zor olayın tüketilmemesi anlamına geldiğini söyledi. Ancak gerçek tamamen tersidir.
Kai Wang


12

Boole değeri, olayın tüketilip tüketilmediğini belirler.

Evet haklısın. Yanlış döndürürseniz, bir sonraki dinleyici olayı işler. True döndürürse, olay dinleyiciniz tarafından tüketilir ve sonraki yönteme gönderilmez.


2
Bu yanlış. trueolayı tükettiğiniz ve olayların geri kalanını harekette istediğiniz anlamına gelir - diğer dinleyiciler / görünümler olayları almayacaktır. falsebaşka birinin olayı yönetmesine izin vermek anlamına gelir. Aslında bundan biraz daha spesifik; cevabımı gör.
adamp

Nasıl tam olarak böyle söylemedim?
Falmarri

1
Söylediğin şey tersine döndü. :)
adamp

4

Yukarıdaki tüm cevaplar doğrudur, ancak sonuç farklıdır, Görünüm olup clickableolmadığıdırclickable

Örnek , bunun gibi LinearLayout1 Buttonve 1 içeren bir varTextView

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

Aktivitede, gibi kodum var

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

Durum 1 Linear onTouch return **FALSE**, Button onTouch return **FALSE**,TextView onTouch return **FALSE**

Düğmeye tıklayın

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

TextView'a tıklayın

TAG: TextView onTouch eventDOWN
TAG: LinearLayout onTouch eventDOWN

LinearLayout'a tıklayın

TAG: LinearLayout onTouch eventDOWN

Durum 2 Linear onTouch return **FALSE**, Button onTouch return **TRUE**,TextView onTouch return **TRUE**

Düğmeye tıklayın

Similar to case 1

TextView'a tıklayın

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

LinearLayout'a tıklayın

Similar to case 1

Vaka 3 Linear onTouch return **TRUE**, Button onTouch return **FALSE**,TextView onTouch return **FALSE**

Düğmeye tıklayın

Similar to case 1

TextView'a tıklayın

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

LinearLayout'a tıklayın

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

Not

  • Varsayılan TextViewolduğunu not clickablebelirlediğimiz eğer tıklanabilir hale gelir, android:clickable="true"xml VEYA biz ayarladığınızdatextView.setOnClickListener(...)
  • Hata ayıkladığınızda, event MOVEgünlüğümden fazlasını arayabilir (nasıl dokunduğunuza bağlıdır)

özet

  • onTouchiade trueveya görünüm clickable , Görünüm tümünü alacak onTouchEvent
  • onTouchreturn falseve view değil clickable, view NEXT onTouchEvent'i almayacak (ebeveyn onu alabilir)

O yardım Umut
DEMO


1
Cevap bu olmalı! Böylesine ayrıntılı bir açıklama için teşekkürler
Mysterious_android

1

Sorun gidermede neredeyse bir gün kaybettim, yine de öğrendim ki onTouch işlevim true kullanılırken 2 kez ve false kullanırken 1 kez çağrıldı.


Sebebini bulabilir misin?
Bhargav Jhaveri

kontrol event.getAction()eğer dönerseniz çünkü falseACTION_DOWN olayı, ACTION_UP olay dinleyicisi tarafından göz ardı edilir
doodeec

0

Gönderen Android belgede :

Not: Android birinci ve ardından sınıf tanımı saniyede uygun varsayılan işleyicileri olay işleyicileri arayacak. Bu nedenle, bu olay dinleyicilerinden true değerinin döndürülmesi, olayın diğer olay dinleyicilerine yayılmasını durduracak ve ayrıca Görünüm'deki varsayılan olay işleyicisine geri çağrıyı da engelleyecektir. Bu nedenle, true'ya döndüğünüzde olayı sonlandırmak istediğinizden emin olun.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.