Kotlin addTextChangeListener 람다?
Kotlin에서 EditText addTextChangeListener에 대한 람다 표현식을 어떻게 빌드하나요? 아래는 오류를 제공합니다.
passwordEditText.addTextChangedListener { charSequence ->
try {
password = charSequence.toString()
} catch (error: Throwable) {
raise(error)
}
}
addTextChangedListener()
얻어 TextWatcher
3 방법에 대한 인터페이스를이다. 당신이 쓴 것은 TextWatcher
오직 하나의 방법 만있는 경우에만 작동합니다 . 나는 당신이 얻는 오류가 다른 두 가지 방법을 구현하지 않는 람다와 관련이 있다고 추측 할 것입니다. 앞으로 두 가지 옵션이 있습니다.
1) 람다를 버리고 익명의 내부 클래스를 사용하십시오.
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
})
2) 람다 식을 사용할 수 있도록 확장 메서드를 만듭니다.
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString())
}
})
}
그런 다음 확장을 다음과 같이 사용하십시오.
editText.afterTextChanged { doSomethingWithText(it) }
이 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
조금 오래되었지만 Kotlin Android 확장 프로그램을 사용하면 다음과 같이 할 수 있습니다.
editTextRequest.textChangedListener {
afterTextChanged {
// Do something here...
}
}
추가 코드가 필요하지 않으며 다음을 추가하십시오.
implementation 'androidx.core:core-ktx:1.0.0'
if you use implementation 'androidx.core:core-ktx:1.1.0-alpha05'
you can use
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)
Test it :
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) {
}
})
Another alternative is the KAndroid
library -
implementation 'com.pawegio.kandroid:kandroid:0.8.7@aar'
Then you could do something like this...
editText.textWatcher { afterTextChanged { doSomething() } }
Obviously it is excessive to use an entire library to solve your problem, but it also comes with a range of other useful extensions that eliminate boilerplate code in the Android SDK.
You can make use of kotlin's named parameters:
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)
}
})
You simply have to do
passwordEditText.doAfterTextChanged{ }
This looks neat:
passwordEditText.setOnEditorActionListener {
textView, keyCode, keyEvent ->
val DONE = 6
if (keyCode == DONE) {
// your code here
}
false
}
참고URL : https://stackoverflow.com/questions/40569436/kotlin-addtextchangelistener-lambda
'IT박스' 카테고리의 다른 글
장고는 존재하지 않습니다 (0) | 2020.10.31 |
---|---|
Gradle의 종속성 캐시가 손상되었을 수 있습니다 (이는 때때로 네트워크 연결 시간 초과 후에 발생합니다.) (0) | 2020.10.31 |
"직면 한 프로젝트 문제 (Java 버전 불일치)"오류 메시지 (0) | 2020.10.31 |
PHP의 동적 상수 이름 (0) | 2020.10.31 |
node.js rmdir은 재귀 적입니까? (0) | 2020.10.31 |