kotlin - проверяет, был ли контент editText изменен пользователем или программно - PullRequest
0 голосов
/ 31 октября 2018

У меня есть 2 editTexts. При изменении editText1 содержимое editText2 будет равно editText1 * 5. При изменении editText2 содержимое editText1 будет равно editText2 * 5.

Теперь, если я использую addTextChangedListener(), он зацикливается, потому что содержимое editTexts всегда будет меняться, вызывая сбой. Мне нужно определить, изменяются ли editTexts пользователем или программно.

Есть идеи?

Если можете помочь, вот мой код:

     fun EditText.doubleValue() = text.toString().toDoubleOrNull() ?: 0.0

     editText1.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}

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

            override fun afterTextChanged(editable: Editable) {

               editText2.setText(editText1.doubleValue() * 5)
            }
        })



editText2.addTextChangedListener(object : TextWatcher {
                override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}

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

                override fun afterTextChanged(editable: Editable) {

                   editText1.setText(editText2.doubleValue() * 5)
                }
            })

РЕДАКТИРОВАТЬ: РЕШЕНО

Я использовал if(editText.isFocused), чтобы проверить, был ли пользователь изменен

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

Вы можете сохранять TextWatchers в переменных, удалять их перед программным изменением содержимого каждого TextView, а затем добавлять их обратно.

class MyActivity: AppCompatActivity() {

  private val textWatcher1 = object : TextWatcher {
    override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}

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

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

  fun EditText.doubleValue() = text.toString().toDoubleOrNull() ?: 0.0

  private val textWatcher2 = object : TextWatcher {
    override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}

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

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

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    editText1.addTextChangedListener(textWatcher1)
    editText2.addTextChangedListener(textWatcher2)
  }


  private fun updateEditText1() {
    editText1.removeTextChangedListener(textWatcher1)
    editText1.setText(editText2.doubleValue() * 5)
    editText1.addTextChangedListener(textWatcher1)
  }

  private fun updateEditText2() {
    editText2.removeTextChangedListener(textWatcher2)
    editText2.setText(editText1.doubleValue() * 5)
    editText2.addTextChangedListener(textWatcher2)
  }
}
0 голосов
/ 31 октября 2018

Прежде всего удалите функцию doubleValue(), она не работает (или, по крайней мере, я не смог заставить ее работать).
Используйте 2 логические переменные from1 и from2, указывающие, что изменение, которое должно быть сделано, происходит из кода и проверьте их значения в наблюдателях.
Скажите, что вы печатаете внутри editText1.
Текстовый наблюдатель editText1 перед изменением значения editText2 устанавливает from1 = true.
Когда текст editText2 изменяется, текстовый наблюдатель editText2 проверяет значение from1 и, поскольку он true ничего не делает, только устанавливает from1 = false.

var from1 = false;
var from2 = false;

editText1.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}

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

    override fun afterTextChanged(editable: Editable) {
        if (from2) {
            from2 = false
        } else {
            val value = editText1.text.toString().toDoubleOrNull() ?: 0.0
            from1 = true
            editText2.setText((value * 5).toString())
        }
    }
})

editText2.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}

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

    override fun afterTextChanged(editable: Editable) {
        if (from1) {
            from1 = false
        } else {
            val value = editText2.text.toString().toDoubleOrNull() ?: 0.0
            from2 = true
            editText1.setText((value * 5).toString())
        }
    }
})
0 голосов
/ 31 октября 2018

Я думаю, что лучшим вариантом будет использование параметра actionDone ime. Таким образом, только когда пользователь закончит редактирование поля, другой текст редактирования будет обновлен. Для этого вам нужно добавить android:imeOptions="actionDone" к вашим элементам editText xml el. Тогда в вашем коде вместо прослушивания изменений вы добавите прослушиватель действий:

editText1.setOnEditorActionListener() { v, actionId, event ->
      if(actionId == EditorInfo.IME_ACTION_DONE){
          editText2.setText(editText1.doubleValue() * 5)
          true
      } else {
          false
      }
}

Не зная, какой вариант вы используете, я не знаю, подойдет ли вам это решение. Если вам нужно обновить editTexts в реальном времени, возможно, проверка, находится ли поле в фокусе, может предотвратить бесконечный цикл:

 editText1.addTextChangedListener(object : TextWatcher {
        override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}

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

        override fun afterTextChanged(editable: Editable) {
           if(editText1.hasFocus()) {
             editText2.setText(editText1.doubleValue() * 5)
           }
        }
    })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...