Bagaimana cara meneruskan acara onClick tampilan ke induknya di Android?


100

Saya memiliki TextView dalam tata letak yang latar belakangnya adalah Selector. Dan teks TextView diatur ke Spanned from HTML. Lalu saya mengatur TextView dengan LinkMovementMethod.

Sekarang ketika saya mengetuk TextView, peristiwa klik tidak dikirim ke tata letak induknya untuk memicu selektor.

Bagaimana ini harus diselesaikan?

Jawaban:


45

Saya pikir Anda perlu menggunakan salah satu metode tersebut agar dapat mencegat acara sebelum dikirim ke komponen yang sesuai:

Activity.dispatchTouchEvent(MotionEvent) - Ini memungkinkan Aktivitas Anda untuk mencegat semua peristiwa sentuh sebelum dikirim ke jendela.

ViewGroup.onInterceptTouchEvent(MotionEvent) - Ini memungkinkan ViewGroup untuk menonton acara saat dikirim ke Views turunan.

ViewParent.requestDisallowInterceptTouchEvent(boolean) - Panggil ini pada View induk untuk menunjukkan bahwa itu tidak boleh menghalangi kejadian sentuh dengan onInterceptTouchEvent (MotionEvent).

Informasi lebih lanjut di sini .

Semoga membantu.


1
Apakah ada cara yang lebih mudah untuk meneruskan peristiwa untuk memicu onClick dan onLongClick dalam tampilan induk, atau saya harus menerapkannya sendiri?
shiami

Lihat ini: stackoverflow.com/questions/2136696/pass-event-to-parent-view Mungkin Anda ingin mencoba meneruskan pendengar klik yang sama ke contoh lain seperti yang disarankan, meskipun saya tidak tahu apakah itu akan berhasil , tapi mungkin patut dicoba.
Luis Miguel Serrano

Jawaban di bawah ini jauh lebih bersih
JPM

Haruskah saya membuat instance MotionEvent? Tolong, jelaskan, @LuisMiguelSerrano
olegario

@olegario, biasanya Anda mendefinisikan ulang metode misalnya untuk dispatchTouchEvent, dengan @Override, untuk mendefinisikan perilaku baru untuknya, jadi Anda hanya menerima kejadian gerakan yang telah disediakan sistem untuk aktivitas Anda (atau komponen lain dari aplikasi Anda), dan Anda perlakukan dan / atau teruskan ke sejumlah komponen turunan sesuai dengan aturan Anda sendiri. Sesuatu seperti: @Override public boolean dispatchTouchEvent(MotionEvent ev) { ... }
Luis Miguel Serrano

212

Nyatakan TextViewtidak dapat diklik / difokuskan dengan menggunakan android:clickable="false"dan android:focusable="false"atau v.setClickable(false)dan v.setFocusable(false). Peristiwa klik harus dikirim ke TextViewinduknya sekarang.

catatan:

Untuk mencapai ini , Anda harus menambahkan klik ke langsung parent. atau setel android:clickable="false"dan android:focusable="false"ke induk langsungnya untuk meneruskan pendengar ke induk selanjutnya .


1
Ya ampun jika saya bisa memberikan 100 ini saya akan. Telah mencoba mencari cara untuk membuat sebuah klik hanya berfungsi di ViewPager dan bukan dalam tata letak adaptor dengan TouchImageView yang mengimplementasikan onTouch! Solusi ini bekerja dengan sangat baik.
JPM

1
tetapi bagaimana jika saya ingin menangani acara perubahan Fokus dari EditText?
SweetWisher ツ

2
Skenarionya adalah: Saya memiliki tata letak yang berisi teks edit, tata letak relatif, pemintal, dan tampilan daftar. Saya ingin menyalakan acara sentuh dari tata letak orang tua setiap kali saya menyentuh di mana saja di layar kecuali teks pengeditan dan pemintal
SweetWisher ツ

9
Sesuatu yang penting untuk diingat adalah bahwa jika Anda menggunakannya TextView#setOnClickListener()di TextView, itu menjadi dapat diklik, bahkan jika itu dinyatakan sebagai android:clickable="false", dan bahkan jika ClickListenerdisetel ke null( setOnclickListener(null))
Christian García

3
Fakta menarik: jika dalam TextView ada android:inputTypeatribut, atribut itu akan mengonsumsi peristiwa klik secara diam-diam bahkan dengan clickable: false & focusable: false; dalam kasus saya itu diatur dalam gaya dan saya membutuhkan waktu 30 menit untuk mencari tahu penyebabnya.
Kirill Karmazin

18

Terkadang hanya ini yang membantu:

View child = parent.findViewById(R.id.btnMoreText);
    child.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            View parent = (View) v.getParent();
            parent.performClick();
        }
    });

Varian lain, tidak selalu berfungsi:

child.setOnClickListener(null);

Ini bekerja CardViewsebagai pandangan anak, karena CardViewtampaknya mengabaikan clickable="false"dan focusable="false". Namun, menggunakan setOnTouchListenerdan memanggil onTouchEventinduknya memungkinkan induk untuk menampilkan umpan balik sentuhan (misalnya efek riak).
methodignature

Saya memposting kode yang relevan di bawah ini: stackoverflow.com/a/52928884/5652513 .
methodignature

10

Taruh

android:duplicateParentState="true"

pada anak maka tampilan mendapatkan status drawable-nya (terfokus, ditekan, dll.) dari induk langsungnya, bukan dari dirinya sendiri. Anda dapat mengatur onclick untuk orang tua dan memanggil anak diklik


OP ingin memanggil pendengar klik orang tua ketika anak diklik, bukan sebaliknya.
Farid

3

Jika Anda TextViewmembuat masalah klik, daripada menghapus android:inputType=""dari file xml Anda.


Jika Anda tidak tahu mengapa, saya sarankan Anda tidak melakukannya. Hanya mengatakan ... untuk masing-masing miliknya sendiri.
dell116

Anda harus mengaturnya keandroid:inputType="none"
AZ_

1

Jawaban ini mirip dengan jawaban Alexander Ukhov , hanya saja menggunakan peristiwa sentuh daripada peristiwa klik. Peristiwa tersebut memungkinkan induk untuk menampilkan status penekanan yang tepat (misalnya, efek riak). Jawaban ini juga ada di Kotlin, bukan di Java.

view.setOnTouchListener { view, motionEvent ->
    (view.parent as View).onTouchEvent(motionEvent)
}

0

Jika Anda ingin keduanya OnTouchdan OnClickpendengar tampilan orang tua dan anak keduanya, gunakan trik di bawah ini:

  1. User ScrollView sebagai tampilan Parent dan di dalamnya menempatkan tampilan anak Anda di dalam Relative / LinearLayout.

  2. Jadikan Parent ScrollView android:fillViewport="true"agar View tidak di-scroll.

  3. Kemudian setel OnTouchlistener ke parent dan OnClicklistener ke tampilan Child. Dan nikmati kedua panggilan balik pendengar.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.