Android’de ListView’imizin içerisine EditText koyduğumuzda temelde 2 sorunla karşılaşırız.

  1. EditText’le touch edildiğinde klavyenin açılıp ardından standart klavyeye dönmesi ve EditText’in focusunu kaybetmesi
  2. İlk problem handle edildiğinde, ilk kullanışda EditText’in düzgün çalışıp scroll ya da dataset değişimi sonrası çift tıklamadan klavyeyi açmaması

Her iki durum için de ListView/ ExpandableListView’e sadece bir EditText eklenmesi gerektiğini varsaydım. Bu durumda eğer tek EditText eklenecek ve en başta görünecekse ListView’imize header olarak eklemek en mantıklı çözüm olacaktır. Bu durumda EditText getview’de dönmeyeceği için sorun yaşanmayacaktır. Öte yandan eğer kullandığımız yapı ExpandableListView olmak zorunda ve biz de childGroup’daki bir row’da EditText kullanmamız gerekiyorsa işler değişecektir. Bu durumda aşağıda önerdiğim çözümlerden faydalanılabilinir.

İlk sorunun sebebi ListView’in touch eventini kendine almasıdır. Bu yüzden klavye ilk açıldıktan hemen sonra default’a dönmesi gerçekleşir. Hemen ardından tekrar touch edersek klavye istediğimiz şekliyle açılacaktır. Bu sorunun çözümü için ListView’e xml’de ya da Java’da aşağıdaki kodun eklenmesi gerekmektedir. Bu kod ListView’in içindeki focusable alanların ListView’den önce focus almasını sağlayacaktır. Böylece ilk sorun çözülmüş ve klavye istenilen şekliyle ilk kullanımda tek dokunuşda açılmış olacatır.

android:descendantFocusability="afterDescendants"

listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

 Ancak ilk sorunu çözümledikten sonra 2. problem karşımıza çıkacak. Bunun sebebi de descendantFocusability’yi after verdiğimiz için, EditText’in içindeki focusu hiç kaybetmeyip ilk tıklandığında klavyenin açılması gerektiğini algılayamamasındandır.

Bunun için de bir trick uygulamamız gerekecek. Klavye normal şartlar altında touch edildiğinde açılır, back ya da enter yapıldığında ise kapanır.

İstediğimiz şekilde çalışabilmesi için EditText’in onTouch eventinde eğer ACTION_DOWN’sa listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); set etmelidir. Böylece touch yapıldığı anda focus alma yetkisi EditText’e geçmiş olacaktır.

EditText’in KeyListener’ında actionId’si Enter’sa ve @override edilmiş onKeyPreIme methodunda keycode BACK’mi kontrolü yapılıp EditText’in focus clear edilmesi ve listView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); set edilmelidir. Tabi bu işlemleri yaparken ihtiyaca göre EditText’in extend edilmesi ve listener yazılması gibi durumlar söz konusu olabilir. 🙂 Kolay gelsin 😉