कोटलिन addTextChangeListener lambda?


103

कैसे आप कोटलीन में EditText addTextChangeListener के लिए एक लैम्ब्डा अभिव्यक्ति का निर्माण करते हैं? नीचे एक त्रुटि दी गई है:

passwordEditText.addTextChangedListener { charSequence  ->
    try {
        password = charSequence.toString()
    } catch (error: Throwable) {
        raise(error)
    }
}

2
यह क्या त्रुटि देता है?
वोडदन

जवाबों:


244

addTextChangedListener()एक लेता है TextWatcherजो 3 तरीकों के साथ एक अंतरफलक है। यदि आपने लिखा तो TextWatcherकेवल 1 विधि होने पर ही काम होगा । मैं उस त्रुटि का अनुमान लगाने जा रहा हूं जो आपको अपने लैम्ब्डा से संबंधित है जो अन्य 2 विधियों को लागू नहीं कर रहा है। आपके पास आगे बढ़ने के 2 विकल्प हैं।

  1. लंबोदर खाई और बस एक अनाम आंतरिक वर्ग का उपयोग करें
    editText.addTextChangedListener(object : TextWatcher {
      override fun afterTextChanged(s: Editable?) {
      }
    
      override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
      }
    
      override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
      }
    })
  1. एक विस्तार विधि बनाएं ताकि आप लैम्बडा अभिव्यक्ति का उपयोग कर सकें:
    fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
        this.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(editable: Editable?) {
            afterTextChanged.invoke(editable.toString())
          }
        })
    }

और फिर विस्तार का उपयोग करें जैसे:

editText.afterTextChanged { doSomethingWithText(it) }

4
सुनिश्चित नहीं है कि व्यक्तिगत पसंद या बेहतर शैली, लेकिन आपके एक्सटेंशन फ़ंक्शन को एक अभिव्यक्ति निकाय में परिवर्तित किया जा सकता है ( fun foo() = ...)
एफ। जॉर्ज

6
@ mEQ5aNLrK3lqs3kfSa5HbvsTWe0nIu आप सही हैं कि इसे परिवर्तित किया जा सकता है। हालाँकि, एक पंक्ति से अधिक समय तक कार्य करने के लिए, मुझे स्पष्ट रूप से चिन्हित करना है कि फ़ंक्शन कहाँ शुरू होता है और रुकता है। मेरा मानना ​​है कि यह पठनीयता बढ़ाता है, लेकिन यह पूरी तरह से एक शैली की प्राथमिकता है। मुझे लगता है कि यह दोनों तरीकों से तर्क दिया जा सकता है :)
एंड्रयू ओरोबिएटर

2
ब्याज से बाहर: afterTextChanged.invoke(...)बजाय कॉल क्यों afterTextChanged(...)?
फेलिक्स डी।

इसने मेरे लिए काम किया। मैंने पुन: प्रयोज्य के लिए दूसरा विकल्प पसंद किया।
ओनी मैनिगो

21

थोड़ा पुराना है, लेकिन Kotlin Android एक्सटेंशन का उपयोग करके आप ऐसा कुछ कर सकते हैं:

editTextRequest.textChangedListener {
            afterTextChanged {
                // Do something here...
            }
}

कोई अतिरिक्त कोड की आवश्यकता नहीं है, बस जोड़ें:

implementation 'androidx.core:core-ktx:1.0.0'

4
यह मेरे लिए काम नहीं कर रहा है, यहां तक ​​कि एंड्रॉइड एक्स के लिए रिफैक्टरिंग के बाद भी। क्या मैं गलत कर सकता हूं इसका कोई अनुमान है?
निकोलस शिमर

3
मेरे लिए भी काम नहीं करता है। ऐसा लगता है कि KTX अब इस विस्तार को प्रदान नहीं करता है, हालांकि, KAndroid समाधान पूरी तरह से काम करता है।
इगोर वोजा

2
ktx के साथ: 1.0.1 आप डेवलपर का
ingyesid

16

इस कोर ktx निर्भरता जोड़ें

implementation 'androidx.core:core-ktx:1.0.0'

आपको बस करना है

passwordEditText.doAfterTextChanged{ }


12

उम्मीद है कि यह Kotlinनमूना इसे स्पष्ट करने में मदद करेगा:

class MainFragment : Fragment() {

    private lateinit var viewModel: MainViewModel

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View {
    val view = inflater.inflate(R.layout.main_fragment, container, false)

    view.user.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) {
                userLayout.error =
                        if (s.length > userLayout.counterMaxLength) {
                            "Max character length is: ${userLayout.counterMaxLength}"
                        } else null
        }
    })
    return view
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
    // TODO: Use the ViewModel
   }
}

इस XMLलेआउट के साथ :

<android.support.design.widget.TextInputLayout
    android:id="@+id/userLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:counterMaxLength="5"
    app:counterEnabled="true"
    android:hint="user_name">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/user"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>

और यह Gradle:

android {
    compileSdkVersion 'android-P'
...
}
    api 'com.android.support:design:28.0.0-alpha1'

    implementation 'com.android.support:appcompat-v7:28.0.0-alpha1' // appcompat library

12

झसे आज़माओ :

passwordEditText.addTextChangedListener(object:TextWatcher{override fun afterTextChanged(s: Editable?) {

    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

    }

})

10

यदि आप उपयोग implementation 'androidx.core:core-ktx:1.1.0-alpha05'करते हैं तो आप उपयोग कर सकते हैं

For android.widget.TextView
TextWatcher 
TextView.doBeforeTextChanged(crossinline action: (text: CharSequence?, start: Int, count: Int, after: Int) -> Unit)
Add an action which will be invoked before the text changed.

TextWatcher 
TextView.doOnTextChanged(crossinline action: (text: CharSequence?, start: Int, count: Int, after: Int) -> Unit)
Add an action which will be invoked when the text is changing.

TextWatcher 
TextView.doAfterTextChanged(crossinline action: (text: Editable?) -> Unit)

https://developer.android.com/reference/kotlin/androidx/core/widget/package-summary#extension-functions


4

देर से आने के लिए क्षमा करें!

यदि आप implementation 'androidx.core:core-ktx:1.1.0'अपने मॉड्यूल की build.gradle फ़ाइल में जोड़ते हैं तो आप उपयोग कर सकते हैं

etPlayer1.doOnTextChanged { text, start, count, after -> // Do stuff }

2

एक अन्य विकल्प KAndroidपुस्तकालय है -

implementation 'com.pawegio.kandroid:kandroid:0.8.7@aar'

तब आप ऐसा कुछ कर सकते थे ...

editText.textWatcher { afterTextChanged { doSomething() } }

स्पष्ट रूप से आपकी समस्या को हल करने के लिए एक संपूर्ण पुस्तकालय का उपयोग करना अत्यधिक है, लेकिन यह अन्य उपयोगी एक्सटेंशनों की एक श्रृंखला के साथ आता है जो एंड्रॉइड एसडीके में बॉयलरप्लेट कोड को समाप्त करते हैं।


2

आप कोटलिन के नामित मापदंडों का उपयोग कर सकते हैं:

private val beforeTextChangedStub: (CharSequence, Int, Int, Int) -> Unit = { _, _, _, _ -> }
private val onTextChangedStub: (CharSequence, Int, Int, Int) -> Unit = { _, _, _, _ -> }
private val afterTextChangedStub: (Editable) -> Unit = {}

fun EditText.addChangedListener(
        beforeTextChanged: (CharSequence, Int, Int, Int) -> Unit = beforeTextChangedStub,
        onTextChanged: (CharSequence, Int, Int, Int) -> Unit = onTextChangedStub,
        afterTextChanged: (Editable) -> Unit = afterTextChangedStub
) = addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
        beforeTextChanged(charSequence, i, i1, i2)
    }

    override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
        onTextChanged(charSequence, i, i1, i2)
    }

    override fun afterTextChanged(editable: Editable) {
        afterTextChanged(editable)
    }
})

0

कोर ktx निर्भरता जोड़ें

implementation 'androidx.core:core-ktx:1.3.0'

और आप बस इस तरह से लागू कर सकते हैं

    edit_text.addTextChangedListener { it: Editable? ->
      // Do your stuff here
    }

-9

यह साफ दिखता है:

passwordEditText.setOnEditorActionListener { 
    textView, keyCode, keyEvent ->
    val DONE = 6

    if (keyCode == DONE) {                       
         // your code here
    }
    false
}

1
मैं वास्तव में आप लोगों के साथ नहीं जानता, लेकिन मेरे जवाब ने मेरे लिए काम किया और ऊपर और नीचे के उत्तर से छोटा है ..
LEMUEL ADANE

1
यह उसी तरह काम करता है जैसे कोड होना चाहता है, एक बार DONE दबाए जाने पर कार्रवाई करता है। मैंने शर्त के बाहर एक टोस्ट रखकर कोड को संशोधित किया और यह केवल आग लगने पर लगता है जब TAB / DONE / etc दबाते हैं। लेकिन अन्य पात्रों पर नहीं।
ओनी मैनिगो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.