2010-05-22 23 views
10

OnClickListener içeren bir Düğmem var. Görsel amacıyla, kalıcı bir iletişim kutusu gösteren bir düğme düşünün:Düğmelerdeki hızlı dokunma ile ilgilenme

public class SomeActivity ... { 

    protected void onCreate(Bundle state) { 
    super.onCreate(state); 

    findViewById(R.id.ok_button).setOnClickListener(
     new View.OnClickListener() { 
     public void onClick(View v) { 
      // This should block input 
      new AlertDialog.Builder(SomeActivity.this) 
      .setCancelable(true) 
      .show(); 
     } 
    }); 
} 

Normal kullanımda, uyarı iletişim kutusu görüntülenir ve blok daha girdi. Kullanıcılar, düğmeye tekrar dokunmadan önce iletişim kutusunu kapatmalıdır.

Ancak bazen düğmenin OnClickListener diyalogun görünmesinden iki kez çağrılır. Düğmeye gerçekten hızlı bir şekilde dokunarak bunu kolayca çoğaltabilirsiniz. Genelde birkaç kez denemem gerekiyor, ama er ya da geç diyalog blokları girişinden önce birden fazla onClick (...) çağrısını tetikleyeceğim.

Bu davranışı, Android 2.1'de Motorola Droid telefonunda görüyorum. Market'te, zaman zaman insanlara yapılan 4 kilitlenme raporunu aldık.

OnClickListeners'ın yaptıklarına bağlı olarak, bu her türlü tahribata neden olur. Engelleme diyaloglarının ilk dokunuştan sonra girişi engelleyeceğini nasıl garanti edebiliriz?

+0

AlertDialog'u onClick() öğesinin dışında oluşturmayı denediniz mi ve on() içindeki show() işlevini çağırdınız mı? – jfpoilpret

cevap

17

Romain Guy, bunun gerçekten de Android'de bir hata olduğunu doğruladı: "Kullanıcı yalnızca < 125 ms'de düğmeye iki kez basmayı başarırsa olur. Sanırım Froyo'da bu olası hatayı düzelttiğimize inanıyorum."

Eski işletim sistemlerinde hatayı gidermek için "cam bölme" desenini kullanırız. Yani, ekranı görünmez bir görünümle kaplayacağız. İlk tıklama etkinliğinden sonra, görünümü "görünür" yaparız, böylece sonraki dokunma olaylarını yakalar.

Yalnızca bir düğmeyle başka olayları önlemek için yeterli değil. Tüm aktivitenin tüm aktiviteleri için diyaloğu sonlandırılana, aktiviteye geri dönene kadar vb. Engellemelisiniz, bu noktada cam bölmeyi tekrar "görünmez" yaparsınız.

Bu işe yaramazsa, bununla yaşamak ve beklenmedik ek olayları daha iyi tolere etmek zorundayız.

+0

Vay canına * sen * Bob Lee misin? –

+0

Sanırım bu, Bob Lee'nin kim olduğuna bağlı. :-) Başka Bob Lee programcılarını bilmiyorum. :-) –

+1

Bob ve Bob'un yukarıda tarif ettiği şeye çok benzer bir şeyle gidiyoruz. Ana fark bizim "cam bölme" gerçek bir görünüm değildir. Bunun yerine, tüm Etkinliklerimiz ortak bir baz Faaliyetini genişletir ve tüm diyaloglarımız bir baz diyaloğu genişletir. Bu temel sınıflara sahip olduğumuzdan, her birinde bir boole bayrağı tanıtabiliyoruz. Bu bayrak, girişi kabul edip etmediğimizi gösterir. Bu temel sınıfların her birinde, dispatchTouchEvent öğesini geçersiz kılar. Bayrağa dayanarak, olayı engelleyen ve engelleyen doğruları döndürebiliriz. Bu yaklaşım işe yarıyor gibi görünüyor. –

9

Denediğiniz için teşekkürler, mdma, ama bu bir platform problemidir, kodumuzla ilgili bir sorun değil. Daha da kötüsü, görünüşe göre kullanıcı kodunda çalışılabilecek bir sorun değil (dokunmatik ekran sürücüsünden ayrıntıları geçmeyen detaylar gerektirir). Ayrıca, kod örneğiniz düşündüğün şeyi yapmaz. show() iletişim kutusunu hemen göstermez. Sonunda iletişim kutusunu gösteren etkinlik sırasının sonuna bir ileti ekler. Daha fazla dokunma olayı, onClick() geri döndükten sonra yürütmeyi bekleyen sıradaydı.

İnsanların neden cevap verdiğine oy verdiğinden emin değilim.

+0

Merhaba, cevabımı sildim. Ancak, durumları arasında gidip gelmediğinizi - tıklama işlemlerini gerçekleştirme ve iletişim kutusunu gösterme arasında - ve daha fazla tıklamayı yok saymanın - nasıl mümkün olmadığını göremiyorum. – mdma