TextWatcher एक Android इंटरफ़ेस है जो EditText और अन्य TextView में रीयल टाइम में टेक्स्ट परिवर्तनों को ट्रैक करने की अनुमति देता है। डेवलपर को तीन चरणों में सूचनाएँ प्राप्त होती हैं: परिवर्तन से पहले, परिवर्तन के दौरान, और टेक्स्ट सामग्री के परिवर्तन के बाद। Android Developers, 2026 के अनुसार, TextWatcher का उपयोग अधिकांश अनुप्रयोगों में इनपुट सत्यापन, वर्ण गणना, ऑटोकम्प्लीट के साथ खोज कार्यान्वयन और गतिशील टेक्स्ट फ़ॉर्मेटिंग के लिए किया जाता है। यह इंटरफ़ेस उन फ़ॉर्मों में अपरिहार्य है जहाँ प्रत्येक की प्रेस पर तत्काल प्रतिक्रिया की आवश्यकता होती है।
मुख्य बिंदु
TextWatcher android.text पैकेज का एक इंटरफ़ेस है जो Editable ऑब्जेक्ट्स में टेक्स्ट परिवर्तनों के बारे में एप्लिकेशन को सूचित करता है। प्रत्येक इनपुट, विलोपन या वर्ण प्रतिस्थापन के साथ, TextWatcher क्रमिक रूप से तीन विधियों को कॉल करता है, परिवर्तनों की स्थिति के बारे में जानकारी प्रेषित करता है। यह डेवलपर को बिना अतिरिक्त बटन या ट्रिगर के तुरंत उपयोगकर्ता क्रियाओं पर प्रतिक्रिया करने की अनुमति देता है।
मुख्य उपयोग के मामलों में रीयल टाइम फ़ील्ड सत्यापन शामिल है: प्रत्येक वर्ण टाइप करने पर ईमेल की जाँच करना, लंबाई सीमा वाले फ़ील्ड में शेष वर्णों की गणना करना, डिबाउंस के माध्यम से विलंबित अनुरोध के साथ खोज कार्यान्वित करना। TextWatcher का उपयोग इनपुट फ़ॉर्मेटिंग के लिए भी किया जाता है — उदाहरण के लिए, फ़ोन नंबर में स्वचालित रूप से स्थान जोड़ना या दिनांक के लिए मास्क जोड़ना।
Android Developers के अनुसार, TextWatcher 70% अनुप्रयोगों में मौजूद है जो फ़ॉर्म के साथ काम करते हैं। Material Design Components और TextInputEditText जैसी लाइब्रेरीज़ त्रुटि स्थितियों के प्रबंधन और काउंटर प्रदर्शित करने के लिए आंतरिक रूप से TextWatcher का उपयोग करती हैं। इस इंटरफ़ेस के काम करने की समझ प्रत्येक Android डेवलपर के लिए आवश्यक है।
TextWatcher addTextChangedListener विधि के माध्यम से किसी भी TextView या EditText ऑब्जेक्ट से जुड़ता है। जब उपयोगकर्ता कोई वर्ण टाइप या हटाता है, तो Android पहले beforeTextChanged, फिर onTextChanged, और अंत में afterTextChanged को कॉल करता है। प्रत्येक विधि के पैरामीटर में परिवर्तित श्रेणी के बारे में डेटा होता है: प्रारंभ स्थिति, हटाए गए वर्णों की संख्या, और जोड़े गए वर्णों की संख्या।
यह समझना महत्वपूर्ण है कि afterTextChanged को कॉल करने के बाद, Editable ऑब्जेक्ट में पहले से ही वर्तमान मान होता है। इसलिए, afterTextChanged में फ़ील्ड का अंतिम टेक्स्ट जाँचना सुविधाजनक है। उस क्षण से पहले, डेटा अभी पूरी तरह से अपडेट नहीं हुआ है। डेवलपर अक्सर विधियों के उद्देश्य को भ्रमित करते हैं और अंतिम सत्यापन के लिए onTextChanged का उपयोग करते हैं, हालाँकि सही विकल्प afterTextChanged है।
प्रत्येक वर्ण सम्मिलन, प्रतिस्थापन या विलोपन के साथ, कॉल श्रृंखला पूरी तरह से निष्पादित होने की गारंटी है। हालाँकि, यदि afterTextChanged के अंदर टेक्स्ट बदला जाता है (clear, append, insert के माध्यम से), तो TextWatcher पुनरावर्ती रूप से सक्रिय हो जाएगा। यह Android फ़ॉर्म में StackOverflowError का सबसे सामान्य कारण है। पुनरावृत्ति को रोकने के लिए फ़्लैग-लॉक का उपयोग किया जाता है।
तीनों विधियों में से प्रत्येक टेक्स्ट परिवर्तन के जीवनचक्र में अपनी भूमिका निभाती है। beforeTextChanged(CharSequence s, int start, int count, int after) विधि परिवर्तन लागू करने से पहले कॉल की जाती है। यह स्ट्रिंग की वर्तमान स्थिति, परिवर्तन की प्रारंभ स्थिति, हटाए जा रहे वर्णों की संख्या और जोड़े जा रहे वर्णों की संख्या प्रेषित करती है। यहाँ आप संशोधन से पहले पिछला मान सहेज सकते हैं या शर्तों की जाँच कर सकते हैं।
onTextChanged विधि परिवर्तन के दौरान कॉल की जाती है, जब वर्ण पहले ही हटा दिए गए हों लेकिन नए अभी तक सम्मिलित नहीं हुए हों। पैरामीटर: हटाने के बाद टेक्स्ट, प्रारंभ स्थिति, हटाए गए वर्णों की संख्या, और जोड़े गए वर्णों की संख्या। यह विधि एनिमेशन या लॉगिंग के लिए सुविधाजनक है, लेकिन वास्तविक अंतिम टेक्स्ट के साथ काम करने के लिए नहीं — यह अभी तक एकत्र नहीं हुआ है।
afterTextChanged विधि सबसे अधिक मांग वाली है। यह एक Editable ऑब्जेक्ट प्राप्त करती है और परिवर्तन पूरी तरह से लागू होने के बाद कॉल की जाती है। इस विधि में आप फ़ील्ड का अंतिम मान पढ़ सकते हैं, सत्यापन कर सकते हैं, UI अपडेट कर सकते हैं और टेक्स्ट बदल सकते हैं (पुनरावृत्ति के कारण सावधानी के साथ)।
एक व्यावहारिक उदाहरण — इनपुट फ़ील्ड के लिए वर्ण काउंटर जो प्रत्येक टेक्स्ट परिवर्तन के साथ अपडेट होता है। ऐसा तत्व अक्सर फ़ीडबैक फ़ॉर्म, पोस्ट और लंबाई सीमा वाले संदेशों में पाया जाता है। TextWatcher के माध्यम से कार्यान्वयन में कुछ पंक्तियाँ लगती हैं और इसमें तृतीय-पक्ष लाइब्रेरी की आवश्यकता नहीं होती है।
val editText = findViewById<EditText>(R.id.edit_text)
val counterText = findViewById<TextView>(R.id.counter)
editText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
s: CharSequence?, start: Int,
count: Int, after: Int
) {}
override fun onTextChanged(
s: CharSequence?, start: Int,
before: Int, count: Int
) {}
override fun afterTextChanged(s: Editable?) {
val len = s?.length ?: 0
counterText.text = "$len / 200"
}
})
उदाहरण में, afterTextChanged विधि Editable प्रकार के s पैरामीटर के माध्यम से फ़ील्ड की वर्तमान सामग्री प्राप्त करती है। टेक्स्ट की लंबाई एक अलग TextView में अपडेट की जाती है। इस मामले में, केवल counterText संशोधित किया जाता है, EditText स्वयं नहीं, इसलिए कोई लूप नहीं बनता है। 200 वर्णों की सीमा के लिए, अतिक्रमण के बाद इनपुट को अतिरिक्त रूप से अवरुद्ध किया जा सकता है।
beforeTextChanged और onTextChanged विधियाँ खाली रहती हैं, क्योंकि लंबाई गणना के लिए अंतिम स्थिति पर्याप्त है। यदि प्रत्येक परिवर्तन को लॉग करने की आवश्यकता है, तो onTextChanged में कोड जोड़ा जा सकता है। ऐसा लचीलापन TextWatcher को टेक्स्ट इनपुट के साथ किसी भी परिदृश्य के लिए एक सार्वभौमिक उपकरण बनाता है।
रीयल टाइम सत्यापन UX में काफी सुधार करता है: उपयोगकर्ता सबमिट बटन क्लिक करने के बाद नहीं, बल्कि गलत मान दर्ज करने के तुरंत बाद त्रुटि देखता है। TextWatcher ईमेल, पासवर्ड, फ़ोन नंबर और अन्य फ़ील्ड की तत्काल जाँच की अनुमति देता है। परिणाम EditText पर setError के माध्यम से या त्रुटि संदेश के साथ अलग TextView के माध्यम से प्रदर्शित होता है।
fun validateEmail(emailEditText: EditText) {
emailEditText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
val email = s?.toString () ?: ""
if (email.isNotBlank() &&
!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
emailEditText.error = "Invalid email address"
} else {
emailEditText.error = null
}
}
override fun beforeTextChanged(...) {}
override fun onTextChanged(...) {}
})
}
उदाहरण ईमेल जाँचने के लिए Android SDK से अंतर्निहित Patterns.EMAIL_ADDRESS का उपयोग करता है। यदि टेक्स्ट खाली नहीं है और पैटर्न से मेल नहीं खाता है, तो error प्रॉपर्टी के माध्यम से फ़ील्ड पर त्रुटि सेट की जाती है। सही इनपुट पर त्रुटि साफ़ हो जाती है। खाली फ़ील्ड पर सत्यापन न चलाना महत्वपूर्ण है — उपयोगकर्ता ने अभी तक टाइप करना शुरू नहीं किया होगा, और त्रुटि संदेश समय से पहले होगा।
पासवर्ड और फ़ोन नंबर के लिए, कस्टम रेगुलर एक्सप्रेशन या विशेष लाइब्रेरी का उपयोग किया जाता है। उदाहरण के लिए, पासवर्ड की जटिलता जाँचने के लिए अंकों, बड़े और छोटे अक्षरों की संख्या गिनी जा सकती है। TextWatcher रीयल टाइम में पासवर्ड शक्ति संकेतक को अपडेट करने की अनुमति देता है, जो पंजीकरण रूपांतरण को सकारात्मक रूप से प्रभावित करता है।
पहली और सबसे महत्वपूर्ण गलती पुनरावर्ती कॉल है। यदि afterTextChanged के अंदर उसी EditText का टेक्स्ट बदला जाता है (s.clear(), s.append() या s.insert() के माध्यम से), तो TextWatcher फिर से सक्रिय हो जाएगा। यह एक अनंत लूप बनाता है जो StackOverflowError में समाप्त होता है। समाधान isUpdating फ़्लैग-लॉक का उपयोग करना या जाँचना है कि क्या टेक्स्ट वास्तव में बदला है।
दूसरी सामान्य समस्या मेमोरी लीक है। TextWatcher एक अनाम वर्ग के माध्यम से Activity या Fragment का अंतर्निहित संदर्भ रखता है। यदि View नष्ट होने पर listener नहीं हटाया जाता है, तो कचरा संग्रहकर्ता मेमोरी मुक्त नहीं कर सकता है। समाधान जीवनचक्र घटकों का उपयोग करना या onDestroyView में स्पष्ट रूप से removeTextChangedListener को कॉल करना है।
तीसरी गलती गलत विधि का उपयोग है। कुछ डेवलपर afterTextChanged की प्रतीक्षा किए बिना onTextChanged में अंतिम सत्यापन करते हैं। onTextChanged में, टेक्स्ट अभी पूरी तरह से अपडेट नहीं हुआ है, और अंतिम मान पढ़ने पर गलत डेटा वापस आ सकता है। सही दृष्टिकोण यह है कि अंतिम टेक्स्ट को पढ़ने और जाँचने का सारा तर्क afterTextChanged में होना चाहिए।
| विधि | कॉल का समय | उद्देश्य | क्या अंतिम टेक्स्ट पढ़ सकते हैं? |
|---|---|---|---|
| beforeTextChanged | परिवर्तन से पहले | पिछली स्थिति सहेजना | हाँ |
| onTextChanged | परिवर्तन के दौरान | लॉगिंग, एनिमेशन | नहीं |
| afterTextChanged | परिवर्तन के बाद | सत्यापन, गणना, UI अपडेट | हाँ |
चौथी गलती एकाधिक TextWatcher जोड़ है। यदि एक ही EditText के लिए addTextChangedListener कई बार कॉल किया जाता है, तो सभी listener एक ही परिवर्तन को संसाधित करेंगे। गतिशील View जोड़ वाले फ़ॉर्म में, यह डुप्लिकेट जाँच और अप्रत्याशित व्यवहार की ओर ले जाता है। हमेशा जाँचें कि क्या listener पहले से जोड़ा गया है, या एकल इंस्टेंस का उपयोग करें।
अक्सर पूछे जाने वाले प्रश्न
OnTextChanged टेक्स्ट परिवर्तन के क्षण में कॉल किया जाता है जब नए वर्ण अभी तक नहीं जोड़े गए हैं। यह विधि एनिमेशन और लॉगिंग के लिए उपयुक्त है। AfterTextChanged परिवर्तन पूरी तरह से लागू होने के बाद कॉल किया जाता है और Editable पैरामीटर के माध्यम से अंतिम टेक्स्ट तक पहुँच प्रदान करता है। सत्यापन और मान पढ़ने के लिए afterTextChanged का उपयोग करें।
Boolean प्रकार का फ़्लैग-लॉक उपयोग करें, जो afterTextChanged के अंदर टेक्स्ट बदलने से पहले true पर सेट होता है। विधि की शुरुआत में फ़्लैग जाँचें: यदि true है — बाहर निकलें। वैकल्पिक रूप से, पुराने और नए मानों की तुलना करें और केवल वास्तविक अंतर होने पर टेक्स्ट बदलें।
हाँ, अनिवार्य रूप से. अनाम TextWatcher वर्ग क्लोज़र के माध्यम से Activity का संदर्भ रखता है। यदि listener नहीं हटाया जाता है, तो Activity कचरा संग्रहकर्ता द्वारा एकत्र नहीं की जा सकती। Fragment के लिए onDestroyView या Activity के लिए onDestroy में हमेशा removeTextChangedListener कॉल करें।
हाँ, लेकिन सावधानी के साथ। RecyclerView में, ViewHolders पुनः उपयोग किए जाते हैं, और पिछली स्थिति का TextWatcher सक्रिय रह सकता है। onBindViewHolder विधि में नया सेट करने से पहले हमेशा पुराना TextWatcher हटाएँ। listener का संदर्भ संग्रहीत करने के लिए टैग या ViewHolder के अलग फ़ील्ड का उपयोग करें।
खोज फ़ील्ड के लिए, डिबाउंस (विलंब) के साथ afterTextChanged का उपयोग करें। 300-500 ms का टाइमर लागू करें जो प्रत्येक नए टेक्स्ट परिवर्तन पर रीसेट होता है। यह प्रत्येक की प्रेस पर सर्वर को अनुरोध भेजने से रोकता है और API लोड कम करता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें