Как создать общий класс TextWatcher для нескольких EditText в kotlin? - PullRequest
0 голосов
/ 16 апреля 2019

Я создаю экран подтверждения с 4 EditText. И я создаю один общий подкласс TextWatcher в Kotlin: см. Код ниже (код может быть правильным или неправильным).

Когда я использую приведенный ниже код, приложение вылетает.

view.etTwo.requestFocus ()

Crash Log

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) {}
}

Ответы [ 2 ]

0 голосов
/ 16 апреля 2019

view.etTwo имеет значение null, так как view - это 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 ()
}

Затем в своей деятельности, где у вас есть edittexts, вызвать что-то вроде этого:

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

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

Это создает новый метод в EditText с именем onTextChange (может вызываться как угодно).Этот метод вызывает ваш OnAfterTextChangedListener в вашей деятельности, где у вас есть доступ ко всем вашим правкам.И он будет вызван afterTextChanged, если длина текста равна 1.

0 голосов
/ 16 апреля 2019

проблема в том, что вы пытаетесь выбрать etOne, etTwo, etThree & etFour из ВНУТРИ представление, которое вы получаете на TextWatcher. Доступ к представлению в функции afterTextChanged(s: Editable?) это уже editTexts, на которые вы готовы requestFocus().

Вид, к которому вы обращаетесь, - один из 4 TextView, которые у вас есть. Вам необходимо изменить логику здесь, чтобы иметь доступ к другим TextView s

...