Сбой EditText при очистке текста - PullRequest
0 голосов
/ 12 декабря 2018

Я хочу очистить текст от EditText.Я попытался:

  • editText.setText("")
  • editText.text.clear()
  • editText.editableText.clear()

, и это работает. Но иногда естьисключение.

2018-12-11 16:23:44.367 13388-13388/com.example.helios.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.helios.myapplication, PID: 13388
    java.lang.IndexOutOfBoundsException: setSpan (0 ... 6) ends beyond length 0
        at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1265)
        at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:684)
        at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:677)
        at android.widget.Editor$SuggestionsPopupWindow.updateSuggestions(Editor.java:3608)
        at android.widget.Editor$SuggestionsPopupWindow.show(Editor.java:3480)
        at android.widget.Editor.replace(Editor.java:359)
        at android.widget.Editor$3.run(Editor.java:2129)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776

Я выполняю этот код из переопределенного performClick() (я создаю подкласс EditText).

Кажется, что EditText не понимает, что он должен отменить /забыть механизм предложения, и он не работает.

Знаете ли вы, что я должен сделать, чтобы отменить / предотвратить предложения, которые не сработали?

Я заметил, что исключение происходит, если я делаю всплывающее окночтобы появиться, затем дважды щелкните по X (первый закрывает всплывающее окно, второй выполняет очищающий код).

Обновление:

Соответствующие части кода.Фактический код имеет систему плагинов для добавления различных рисунков и действий, но соответствующий код:

    class MyEditText(..): EditText(context) {
    ... 
        override fun onTouchEvent(event: MotionEvent?): Boolean {
            event!!
            ensureDrawingInfo()
            when (event.actionMasked) {
                MotionEvent.ACTION_DOWN, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
                    lastTouchArea = pluginAreaFromMotionEvent(event)
                }
            }
            return super.onTouchEvent(event)
        }

        override fun performClick(): Boolean {
            lastTouchArea?.let {
                plugins[it.pluginIndex].onClick(this, it.rightSide, ::invalidateDrawingInfo)
                return true
            }
            return super.performClick()
        }


    class MyPlugin(val drawableLeft: Drawable, val drawableRight: Drawable) : Plugin {
        ....

        override fun onClick(editText: MyEditText, rightSide: Boolean, redraw: () -> Unit) {
            if (rightSide) {
                // X
                editText.text.clearSpans()
                editText.text.clear()
            }
        }
    }

1 Ответ

0 голосов
/ 13 декабря 2018

Я нашел способ избежать этой проблемы: использование интересующих меня сенсорных событий.

Я хочу реагировать на нажатия в определенном углу поля редактирования (например, кнопку с открытым текстом илипароль просмотра один).

Сначала я попытался использовать только onTouchEvent, потому что мне были нужны координаты.Но среда IDE предупредила меня о том, что не нужно переопределять executeClick из соображений доступности.Идея состоит в том, что если вы добавите дополнительное поведение при касании, оно должно быть доступно и инструментам специальных возможностей, которые вызывают performClick.

Но это не так.Дополнительные кнопки - это дополнительная функциональность, которая не должна быть доступна.Или, если он доступен, он не будет доступен как обычный / общий щелчок в поле редактирования.Может быть, как действие доступности, реализованное где-то еще.

Итак, вывод: я могу использовать только onTouchEvent и потреблять события.

Решение

override fun onTouchEvent(event: MotionEvent?): Boolean {
        event!!
        ensureDrawingInfo()
        val touchArea = pluginAreaFromMotionEvent(event)
        if (touchArea != null) {
          // it's the special place, I will handle this
          when (event.actionMasked) {
              MotionEvent.ACTION_DOWN -> lastTouchArea = touchArea
              MotionEvent.ACTION_CANCEL -> lastTouchArea = null
              MotionEvent.ACTION_UP -> {
                if (lastTouchArea == touchArea) { // proper click on place
                  // call the plugin
                  plugins[touchArea.pluginIndex].onClick(this, it.rightSide, ::invalidateDrawingInfo)
              }
          }
          // consume touch events that happen on MY area
          return true
        }
        return super.onTouchEvent(event)
    }

Почему

Редактор EditText иногда открывает окно предложения в ответ на сенсорные события.И он хочет заменить текст в определенной позиции.Но это не заменит это сразу.Он ставит в очередь сообщение, которое будет обработано позже, используя зацикливание), поэтому, когда замена произойдет, я мог изменить текст.Я даже пытался поставить в очередь свой очищающий код в надежде, что это произойдет позже, но мне не повезло.

Самое чистое решение - использовать события относительно областей, которые я обрабатываю, чтобы редактор не провоцировалникаких проблем.

На самом деле, запустив это на эмуляторе API 27, я не смог воспроизвести ошибку.Я думаю, что код редактора изменился, чтобы он знал, что текст мог быть изменен между ними.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...