Bir görünümün onClick olayını Android'de üstüne nasıl geçirebilirim?


100

Arka planı Seçici olan bir düzende bir TextView var. Ve TextView'in metni HTML'den Yayılmış olarak ayarlanır. Sonra TextView'i LinkMovementMethod ile ayarlıyorum.

Artık TextView'e dokunduğumda, tıklama olayı seçiciyi tetiklemek için üst düzenine gönderilmiyor.

Bu nasıl çözülmeli?

Yanıtlar:


45

Uygun bileşenlere gönderilmeden önce olayı yakalayabilmek için bu yöntemlerden birini kullanmanız gerektiğini düşünüyorum:

Activity.dispatchTouchEvent(MotionEvent) - Bu, Aktivitenizin tüm dokunma olaylarını pencereye gönderilmeden önce kesmesini sağlar.

ViewGroup.onInterceptTouchEvent(MotionEvent) - Bu, ViewGroup'un olayları alt Görünümlere gönderilirken izlemesine olanak tanır.

ViewParent.requestDisallowInterceptTouchEvent(boolean) - onInterceptTouchEvent (MotionEvent) ile dokunma olaylarını engellememesi gerektiğini belirtmek için bunu bir üst öğe Görünümü'ne çağırın.

Daha fazla bilgi burada .

Umarım yardımcı olur.


1
Üst görünümde onClick ve onLongClick'i tetiklemek için olayları geçirmenin daha kolay bir yolu var mı yoksa bunları kendim uygulamalı mıyım?
shiami

Şuna bir göz atın: stackoverflow.com/questions/2136696/pass-event-to-parent-view Çalışıp çalışmayacağını bilmesem bile, aynı tıklama dinleyicisini önerilen diğer örneklere iletmeyi deneyebilirsiniz. ama denemeye değer olabilir.
Luis Miguel Serrano

Aşağıdaki cevap çok daha temiz
JPM

MotionEvent'i başlatmalı mıyım? Lütfen açıklayın, @LuisMiguelSerrano
olegario

@olegario, tipik olarak bunun için yeni bir davranış tanımlamak üzere dispatchTouchEvent yöntemini yeniden tanımlarsınız, böylece sistem tarafından etkinliğinize (veya uygulamanızın başka bir bileşenine) sağladığı bir hareket olayını alırsınız ve siz kendi kurallarınıza göre ele alın ve / veya istediğiniz sayıda çocuk bileşenine iletin. Şunun gibi bir şey: @Override public boolean dispatchTouchEvent(MotionEvent ev) { ... }
Luis Miguel Serrano

214

Senin beyan TextViewkullanarak değil tıklanabilir / odaklanabilir android:clickable="false"ve android:focusable="false"ya v.setClickable(false)ve v.setFocusable(false). Tıklama olayları TextViewşimdi 'nin üst kuruluşuna gönderilmelidir .

Not:

Bunu başarmak için doğrudan tıklama eklemelisiniz parent. veya set android:clickable="false"ve android:focusable="false"doğrudan ebeveyne ileri ebeveyne dinleyici geçmek .


1
Oh adamım eğer bunu +100 verebilirsem verirdim. TouchImageView onTouch uygulayan TouchImageView ile adaptörler düzeninde değil, bir tıklamanın yalnızca ViewPager'da nasıl çalışacağını anlamaya çalışıyordum! Bu çözüm harika çalıştı.
JPM

1
ama ya EditText'in Odak değişikliği olayını işlemek istersem?
SweetWisherツ

2
Senaryo şudur: edittext, göreceli düzen, döndürücü ve liste görünümünü içeren bir düzenim var. Ekranda edittext ve döndürücü hariç herhangi bir yere dokunduğumda ebeveyn düzeninin dokunma olayını ateşlemek istiyorum
SweetWisher ツ

9
Unutulmaması gereken önemli bir nokta, TextView#setOnClickListener()üzerinde kullanırsanız , TextViewolarak bildirilse android:clickable="false"ve ( ) ClickListenerolarak ayarlanmış olsa bile tıklanabilir hale gelmesidirnullsetOnclickListener(null)
Christian García

3
Eğlenceli gerçek: TextView'da bir android:inputTypeöznitelik varsa, tıklanabilir: false & focusable: false; benim durumumda bir tarzda ayarlanmıştı ve sebebini bulmam 30 dakikaya mal oldu.
Kirill Karmazin

18

Bazen yalnızca bu yardımcı olur:

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

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

Başka bir varyant, her zaman işe yaramaz:

child.setOnClickListener(null);

Bu çalıştı CardViewberi, çocuk görünümü olarak CardViewgörmezden görünüyor clickable="false"ve focusable="false". Bununla birlikte, ebeveynin kullanılması setOnTouchListenerve çağrılması onTouchEvent, ebeveynin dokunma geri bildirimini görüntülemesine izin verir (örn. Dalgalanma etkisi).
yöntem imzası

Aşağıda ilgili kodu gönderdim: stackoverflow.com/a/52928884/5652513 .
yöntem imzası

10

Koymak

android:duplicateParentState="true"

çocukta o zaman görünümler çekilebilir halini (odaklanmış, basılı, vb.) kendisinden ziyade doğrudan ebeveyninden alır. ebeveyn için onclick ayarlayabilir ve tıklanan çocuğu çağırabilirsiniz


OP, çocuk tıklandığında ebeveynin tıklama dinleyicisini aramak ister, akıllıca değil.
Farid

3

Eğer senin TextViewkaldır daha Sorunları tıklayın oluşturmak android:inputType=""xml dosyasından.


Nedenini bilmiyorsanız, yapmamanızı tavsiye ederim. Sadece söylüyorum ... her birine kendi.
dell116

android:inputType="none"
Şuna

1

Bu cevap Alexander Ukhov'un cevabına benzer , tek farkı tıklama olayları yerine dokunma olaylarını kullanmasıdır. Bu olay, ebeveynin uygun basılmış durumları göstermesine izin verir (örneğin, dalgalanma etkisi). Bu cevap da Java yerine Kotlin'de.

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

0

Her iki istiyorsanız OnTouchve OnClickebeveyn ve çocuk görünümüne dinleyici hem hile aşağıda kullanın:

  1. Kullanıcı ScrollView bir Üst görünüm olarak ve bunun içinde çocuğunuzun görünümünü Relative / LinearLayout içine yerleştirdi.

  2. Ebeveyn ScrollView yapın, android:fillViewport="true"böylece Görünüm kaydırılmasın.

  3. Ardından OnTouchdinleyiciyi üst öğe ve OnClickdinleyiciyi Alt görünümler olarak ayarlayın. Ve her iki dinleyici geri aramasının da keyfini çıkarın.

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.