如何在Kotlin中为多个EditText创建TextWatcher公共类?

时间:2019-04-16 11:31:26

标签: android kotlin android-edittext textwatcher

我正在创建一个包含4个EditText的验证屏幕。我在Kotlin中创建了一个TextWatcher的通用子类:请参见下面的代码(代码可能是对还是错)。

当我使用以下代码时,它会使应用程序崩溃。

  

view.etTwo.requestFocus()

崩溃日志

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.widget.EditText.requestFocus()' on a null object reference
        at com.mindfulness.greece.activity.ConfirmationCodeActivity$GenericTextWatcher.afterTextChanged(ConfirmationCodeActivity.kt:123)
        at android.widget.TextView.sendAfterTextChanged(TextView.java:8007)

这是类:

class GenericTextWatcher(var view: View) : TextWatcher {
    override fun afterTextChanged(s: Editable?) {
        val text: String = s.toString();
        when(view.id) {
            R.id.etOne -> {
                 if(text.length==1){
                      view.etTwo.requestFocus()
                 }
            }
            R.id.etTwo -> {
                 if(text.length==1){
                     view.etThree.requestFocus()
                 }
            }
            R.id.etThree -> {
                if(text.length==1){
                     view.etFour.requestFocus()
                }
            }
             R.id.etFour -> {}

                }
            }

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

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

3 个答案:

答案 0 :(得分:0)

问题是您试图从 INSIDE 视图中选择etOneetTwoetThreeetFour TextWatcher。 您在函数afterTextChanged(s: Editable?)中访问的视图 已经是您愿意requestFocus()启用的editTexts。

您正在访问的视图是您拥有的4个TextView之一。您需要在此处更改逻辑以访问其他TextView

答案 1 :(得分:0)

view.etTwo为null,因为view是您当前正在编辑的EditText,它不包含所有其他edittext。

您可以调用view.getParent()列出父级中的所有视图,找到下一个并专注于该视图。很多工作!

或者使它更通用,您可以像这样扩展EditText:

fun EditText.onTextChange(onAfterTextChanged: OnAfterTextChangedListener) {
    addTextChangedListener(object :TextWatcher{
        private var text = ""

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

        override fun afterTextChanged(s: Editable?) {
            if (s?.length == 1) {
                onAfterTextChanged.complete()
            }
        }

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

interface OnAfterTextChangedListener {
    fun complete ()
}

然后在您具有编辑文本的活动中,调用如下内容:

etOne.onTextChange(object: OnAfterTextChangedListener {
    override fun complete() {
        etTwo.requestFocus()
    }
})

etTwo.onTextChange(object: OnAfterTextChangedListener {
    override fun complete() {
        etThree.requestFocus()
    }
})

这将在EditText中创建一个名为onTextChange的新方法(可以称为任何方法)。此方法将回调到“活动”中的OnAfterTextChangedListener,您可以在其中访问所有编辑文本。如果文本的长度等于1,它将被称为afterTextChanged。

答案 2 :(得分:0)

用于多个EditText的TextWatcher通用类

class GenericTextWatcher internal constructor(private val view: View) :
    TextWatcher {
    override fun afterTextChanged(editable: Editable) { // TODO Auto-generated method stub
        val text = editable.toString()
        when (view.id) {
            R.id.otp1 -> if (text.length == 1) edit1.requestFocus()
            R.id.otp2 -> if (text.length == 1) edit2.requestFocus() else if (text.isEmpty()) edit1.requestFocus()
            R.id.otp3 -> if (text.length == 1) edit3.requestFocus() else if (text.isEmpty()) edit2.requestFocus()
            R.id.otp4 -> if (text.isEmpty()) edit4.requestFocus()
        }
    }

    override fun beforeTextChanged(
        arg0: CharSequence,
        arg1: Int,
        arg2: Int,
        arg3: Int
    ) { // TODO Auto-generated method stub
    }

    override fun onTextChanged(
        arg0: CharSequence,
        arg1: Int,
        arg2: Int,
        arg3: Int
    ) { // TODO Auto-generated method stub
    }
}

像这样在课堂上使用

edit1.addTextChangedListener(GenericTextWatcher(edit1))
edit2.addTextChangedListener(GenericTextWatcher(edit2))
edit3.addTextChangedListener(GenericTextWatcher(edit3))
edit4.addTextChangedListener(GenericTextWatcher(edit4))