Our SuccessKnowledges
NEXTZY Logo
Crews
Chat
Talk with Team
NEXTZY Logo
NEXTZY
Chat
Home>Knowledges

ใช้ TextWatcher กับ EditText ให้ถูกวิธีเพื่อ UX ที่ดี

Share:

ใช้ TextWatcher กับ EditText ให้ถูกวิธีเพื่อ UX ที่ดี

Table of contents

  • Tips
  • ปัญหา
  • แก้ไขให้ถูกต้อง
Nonthawit

Nonthawit

CEO | Engineer | Designer

VIEW

5,210

CATEGORY

Technical

LAST UPDATED

July 29, 2017

Nonthawit

Nonthawit

CEO | Engineer | Designer

VIEW

5,210

CATEGORY

Technical

LAST UPDATED

July 29, 2017

nontravis/format-edit-text-example
Contribute to format-edit-text-example development by creating an account on GitHub.github.com

เนื่องจากเจ้าของบล็อกเคยได้โจทย์ให้ใส่ phone format ใหักับตัว EditText สิ่งแรกที่คิดขึ้นมาคงหนีไม่พ้น TextWatcher เป็นแน่แท้

แต่เราเจอปัญหาคือ user ไม่สามารถพิมพ์เบอร์เร็วๆได้ทำให้เกิด UX ที่แย่กับ user มาก และไม่สามารถกดค้างเพื่อลบตัวเลขแบบเร็วๆได้ด้วยซึ่งวันนี้เราจะมาดูสาเหตุและทำให้มันถูกต้องกัน

EditText.addTextChangedListener( new TextWatcher(){
    @Override
public void beforeTextChanged( CharSequence charSequence, int i, int i1, int i2 ){
...
}

@Override
public void onTextChanged( CharSequence charSequence, int i, int i1, int i2 ){
...
}

@Override
public void afterTextChanged( Editable editable ){
...
}
} );

Tips

  1. EditText.addTextChangedListener(…) ชื่อ method เป็น add ซึ่งนั่นหมายความ TextWatcher สามารถ add เข้าไปได้หลายตัว และสามารถสั่ง EditText.removeTextChangedListener(…) ได้ด้วย
  2. param ที่ส่งเข้ามาเป็น CharSequence กับ Editable ไม่มี String เลย เป็นไปได้อย่าเอา String เข้ามายุ่งเกี่ยวให้ใช้ StringBuilder จะดีกว่า
StringBuilder textBuilder = new StringBuilder(); เป็นต้น

NOTE: Editable เป็นแค่ interface นะ object จริงๆที่ส่งเข้ามาคือ SpannableStringBuilder

ปัญหา

จากโค้ดตัวอย่างใน Github

อธิบายการทำงานคร่าวๆของโค้ดด้านบนอาจดูซับซ้อนซักหน่อยแต่หลักๆคือ การดักตัวอักษรที่ user พิมพ์เข้ามาแล้วเอามาก map กับ ###-####-#### format นั่นเอง (สามารถไปดูละเอียดได้ที่ link Github) เช่น

09212345678 --เป็น--> 092-1234-5678
แล้วเก็บไว้ในตัวแปร "strResult"

NOTE: สังเกตใน method TextWatcher.afterText(…) เราสั่ง EditText.removeTextChangedListener( this ) ตอนแรก และ EditText.addTextChangedListener( this ) ตอนสุดท้าย เพราะถ้าเราไม่ทำอย่างนี้ TextWatcher จะถูกเรียกขึ้นมาใหม่อีกถ้าเราสั่ง EditText.setText(…) มันจะทำให้ program เราติด infinity loop ไปเรื่อยๆนั่นเอง

ต่อมาให้สังเกตบรรทัดที่ 44

edt.setText( strResult );

method เจ้าปัญหาที่ไม่ควรใช้ใน TextWatcher เป็นอันขาด ถ้าเข้าไปดูโค้ดข้างในกันเล่นๆ เราก๊อปมาให้ละ

>>What!!?<< นี่ EditText.setText(…) จริงๆใช่ไหมทำไมมันทำอะไรเยอะแยะขนาดนั้น

ใช่ครับมันเป็น method ที่หนักพอสมควรเลยเราขอไม่ไล่ให้ดูนะว่ามันทำอะไรบ้าง ซึ่งการที่นำมาใช้กับ TextWatcher จึงเป็นบาปมหันต์ เพราะทุกครั้งที่เรากดตัวอักษรที่คีย์บอร์ดหนึ่งตัวเพื่อใส่ลง EditText เจ้า TextWatcher จะทำงานและ setText(…) ใหม่ทุกครั้ง ซึ่งเป็นสามารถเหตุว่า user ไม่สามารถพิมพ์ตัวเลขได้เร็วๆรวมถึงการกดค้างเพื่อลบตัวเลขในทีเดียวด้วยเนื่องจาก event มันถูก cancel ไป 😫

เราจึงควรใช้ Editable ที่ส่งเป็น param เข้ามามากกว่า

แก้ไขให้ถูกต้อง

อยากบอกว่าแก้แค่บรรทัดเดียวคือบรรทัดที่ 44 (ที่เดิม)

edt.setText( strResult );
เป็น
s.append( strResult ); จบ 😱

ซึ่ง s ในที่นี้ก็คือ SpannableStringBuilder ที่ส่งเป็น param เข้ามา เราต้องใช้ object ตัวนี้จัดการข้อความใน EditText นะถึงจะถูก เพราะเป็น SpannableStringBuilder.append(…) เป็น method ที่เบากว่า EditText.setText(…) มาก

ถ้าลองเข้าไปดูโค้ดกันเล่นๆ

เราคงไม่ได้ไล่ให้ดู แต่คร่าวๆมันคือการ replace ข้อความ และจัดการเกี่ยวกับข้อความทั้งหมด

คราวนี้การพิมพ์ของ User ก็จะลื่นไหลแล้วครับ หมดปัญหา user ไม่สามารถพิมพ์ตัวเลขได้เร็วๆได้และกดค้างเพื่อลบตัวเลข 😎

วันนี้คงไว้เท่านี้เจอกันบล็อกหน้าครับผม 😎

อย่าลืม share มนุษย์ Android คนอื่นด้วยหละ 😎

Share:

KNOWLEDGE

Related Articles

เข้าใจการทำ Selector แบบ Ripple effect
Nonthawit

Nonthawit

CEO | Engineer | Designer

เข้าใจการทำ Selector แบบ Ripple effect

20 สิ่ง ที่ได้หลังจากเป็น Android developer ที่ Nextzy 3 เดือน
Nonthawit

Nonthawit

CEO | Engineer | Designer

20 สิ่ง ที่ได้หลังจากเป็น Android developer ที่ Nextzy 3 เดือน

บทความนี้แชร์ประสบการณ์ 3 เดือนแรกของการทำงานเป็น Android Developer ที่ Nextzy ครอบคลุมทั้งด้าน technical เช่น MVP architecture, Android Lifecycle, ProGuard, Git workflow และการเขียน Unit Test รวมถึงด้าน soft skill อย่างการสื่อสารกับทีม, การแชร์ความรู้, และการเขียนโค้ดให้ readable และยืดหยุ่น นอกจากนี้ยังสะท้อนวัฒนธรรมองค์กรที่เน้นทีมเวิร์ค การ review โค้ด และบรรยากาศการทำงานที่สนุกสนาน ซึ่งล้วนช่วยลด learning curve และพัฒนาทักษะได้เร็วกว่าการเรียนรู้คนเดียว

[Tip/Trick] วิธีติดต่อกับ WebView ผ่าน JavascriptInterface มันเท่มาก
Nonthawit

Nonthawit

CEO | Engineer | Designer

[Tip/Trick] วิธีติดต่อกับ WebView ผ่าน JavascriptInterface มันเท่มาก

NEXTZY Logo
NEXTZY
48/27 Ratchadaphisek Rd, Samsen Nok, Huai Khwang, Bangkok 10310

Base at Thailand

Thailand

Home

Crews

Success

Download press kits

Knowledges

Chat

Talk with team

SCHEDULE