Android düğmesi üzerinde setOnTouchListener çağrıldı, ancak performClick'i geçersiz kılmıyor


113

Bir onTouchListner()düğmeye eklemeye çalıştığımda , bana

Button setOnTouchListener çağrıldı, ancak performClick'i geçersiz kılmıyor

uyarı. Nasıl düzeltileceğini bilen var mı?

1

btnleftclick.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return false;
    }
});

Hata:

Özel görünüm, setOnTouchListener'ı çağırdı, ancak performClick'i geçersiz kılmıyor onTouchEvent'i geçersiz kılan veya bir OnTouchListener kullanan bir Görünüm, performClick'i de uygulamaz ve tıklamalar algılandığında onu çağırmazsa, Görünüm erişilebilirlik eylemlerini düzgün şekilde işleyemeyebilir. Bazı erişilebilirlik hizmetleri performClick'i çağırdığından tıklama eylemlerini işleyen mantık ideal olarak View # performClick'e yerleştirilmelidir.Bir tıklama eyleminin gerçekleşmesi gerektiğinde.


Özel görünüm ImageView, setOnTouchListener'ı çağırdı, ancak performClick'i geçersiz kılmıyor onTouchEvent'i geçersiz kılan veya bir OnTouchListener kullanan bir Görünüm, performClick'i de uygulamaz ve tıklamalar algılandığında onu çağırmazsa, Görünüm erişilebilirlik eylemlerini düzgün şekilde işleyemeyebilir. Bazı erişilebilirlik hizmetleri performClick'i çağırdığından tıklama eylemlerini işleyen mantık ideal olarak View # performClick'e yerleştirilmelidir.Bir tıklama eyleminin gerçekleşmesi gerektiğinde.
kas

Lütfen cevabıma buradan bakın: stackoverflow.com/questions/47170075/…
lambda

Yanıtlar:


134

Bu uyarı, Android, uygulamanızı kullanabilecek kör veya görme engelli kişiler hakkında düşünmenizi hatırlatmak istediğinden ortaya çıkar. Bunun neye benzediğine dair hızlı bir genel bakış için bu videoyu izlemenizi öneririm .

Standart kullanıcı arayüzü görünümlerinin (gibi Button, TextViewvb.) Tümü, Erişilebilirlik hizmetleri aracılığıyla görme engelli kullanıcılara uygun geri bildirim sağlamak için ayarlanmıştır. Dokunma olaylarını kendiniz halletmeye çalıştığınızda, bu geribildirimi sağlamayı unutmanız tehlikesiyle karşı karşıya kalırsınız. Uyarı bunun için.

1. Seçenek: Özel bir görünüm oluşturun

Dokunma olaylarını işleme, normalde özel bir görünümde yapılan bir şeydir. Bu seçeneği çok çabuk reddetmeyin. Gerçekten o kadar zor değil. TextViewDokunma olaylarını işlemek için geçersiz kılınan tam bir örnek :

public class CustomTextView extends AppCompatTextView {

    public CustomTextView(Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                return true;

            case MotionEvent.ACTION_UP:
                performClick();
                return true;
        }
        return false;
    }

    // Because we call this from onTouchEvent, this code will be executed for both
    // normal touch events and for when the system calls this using Accessibility
    @Override
    public boolean performClick() {
        super.performClick();
        doSomething();
        return true;
    }

    private void doSomething() {
        Toast.makeText(getContext(), "did something", Toast.LENGTH_SHORT).show();
    }
}

O zaman bunu şöyle kullanırdın:

<com.example.myapp.CustomTextView
    android:id="@+id/textview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="20dp"
    android:text="Click me to do something"/>

Özel bir görünüm oluşturma hakkında daha fazla ayrıntı için diğer cevabıma bakın .

Seçenek 2: Uyarıyı susturma

Diğer zamanlarda uyarıyı susturmak daha iyi olabilir. Örneğin, Buttondokunma olaylarına ihtiyacınız olan bir şeyle ne yapmak istediğinizden emin değilim . Özel bir düğme yaparsanız ve yukarıda özel için yaptığım gibi çağrılırsanız performClick(), zaten aradığı için her seferinde iki kez çağrılırdı .onTouchEventTextViewButtonperformClick()

Uyarıyı susturmak isteyebileceğiniz birkaç neden:

  • Dokunma etkinliğinizle gerçekleştirdiğiniz iş yalnızca görseldir. Uygulamanızın gerçek çalışmasını etkilemez.
  • Soğuk kalplisiniz ve dünyayı kör insanlar için daha iyi bir yer haline getirmeyi umursamıyorsunuz.
  • Yukarıdaki 1. Seçenek'te size verdiğim kodu kopyalayıp yapıştırmak için çok tembelsiniz.

Uyarıyı bastırmak için yöntemin başına aşağıdaki satırı ekleyin:

@SuppressLint("ClickableViewAccessibility")

Örneğin:

@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button myButton = findViewById(R.id.my_button);
    myButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            return false;
        }
    });
}

1
Farklı yazı tipleri kullandığım için özel görünümler kullanıyordum. Şimdi Api 26'da olduğu gibi, xml'deki yazı tipleri ve daha eski sürümler için Api 16'ya kadar destekleyen destek kitaplığı 26'yı kullanın. Bu yüzden tüm özel görünümleri kaldırdım. Ve bu aptalca uyarı ortaya çıkıyor ve çözüm, setOnTouchListener'ı kullandığım özel görünümlerden bazılarını yeniden oluşturmak. hahaha: D Çok garip
Shan Xeeshi

19
Merak ediyorum, google bununla kaç geliştirici saatini boşa harcadığını fark edip etmedi. Demek istediğim, bunu api içinde halledebilirler mi? Görünümleri alt sınıflandırmak için zaman harcamak veya hatta uyarısının nasıl çözüleceğini araştırmak çok fazla saat harcıyor.
TatiOverflow

ya yönteminizdeki MotionEvent eventnesneye ihtiyacınız varsa doSomething()? Kontrol etmem gerek event.getY().
Mateus Gondim

@MateusGondim, performClick()henüz uygulama konusunda çok yetkin olmadığımı söylemeliyim . İlk düşüncem, eğer event.getY()gerçek tıklama olayının (yani görsel kullanıcı arayüzü efektleri) ayrılmaz bir parçası değilse, o mantığı geri taşıyın onTouchEvent(). Aksi takdirde, son işlem artış Ydeğerini saklamak için bir sınıf üyesi değişkeni oluşturabilirsiniz . Ayrıca, standart görünümlerden birkaçı için kaynak kodunu kontrol etmenizi öneririm, böylece Android'in bunu nasıl uyguladığını görün. Onları kendim daha fazla incelemem gerekiyor.
Suragch

1
@sisisisi, geçersiz kıldığınızda onTouchEvent()ancak değilken uyarı gelir performClick(). Bu, bir kaydırma veya tıklama ya da yakalamaya çalıştığınız diğer herhangi bir dokunma olayını içerebilir.
Suragch

17

Çözüm:

  1. Button'ı genişleten bir sınıf oluşturun veya kullandığınız ve geçersiz kılan performClick ()

    class TouchableButton extends Button {
    
        @Override
        public boolean performClick() {
            // do what you want
            return true;
        }
    }
  2. Şimdi bu TouchableButton'ı xml ve / veya kodda kullanın ve uyarı kaybolacaktır!


18
Bu gerçekten iğrenç. Mevcut görünümleri kullanmanın bir yolu yok mu?
Milk

@Süt Hayır. android.widget.Buttonkodlanmış olduğundan bunu yapmanıza izin vermez. Ve Android geliştirici ekibinden oldukça bilinçli görünüyor.
tom_mai78101

11

Eklemeyi denediniz mi:

view.performClick()

veya bastırma ek açıklaması ekleyerek:

@SuppressLint("ClickableViewAccessibility")

?


2
Evet. Android stüdyo 3.0 sürümü ile bu Waring comeup
KAS

1
Tamam, bu uyarıyı düzeltmek için bir alternatifim var. lütfen bakınız: stackoverflow.com/questions/47170075/…
lambda

1

Özel görünüm kontrolleri, standart olmayan dokunma olayı davranışı gerektirebilir. Örneğin, özel bir kontrol, ACTION_DOWN ve ACTION_UP olaylarını algılamak ve özel bir tıklama olayını tetiklemek için onTouchEvent (MotionEvent) dinleyici yöntemini kullanabilir. Erişilebilirlik hizmetleriyle uyumluluğu korumak için, bu özel tıklama olayını işleyen kodun aşağıdakileri yapması gerekir:

Yorumlanan tıklama eylemi için uygun bir AccessibilityEvent oluşturun. Dokunmatik ekranı kullanamayan kullanıcılar için özel tıklama eylemi gerçekleştirmek üzere erişilebilirlik hizmetlerini etkinleştirin. Bu gereksinimleri verimli bir şekilde ele almak için, kodunuz performClick () yöntemini geçersiz kılmalıdır; bu yöntemin süper uygulamasını çağırmalı ve ardından click olayının gerektirdiği eylemleri yürütmelidir. Özel tıklama eylemi algılandığında, bu kod daha sonra performClick () yönteminizi çağırmalıdır.

https://developer.android.com/guide/topics/ui/accessibility/custom-views#custom-touch-events

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.