首页 > 解决方案 > 调用 clearSpans 时的 EditText 块

问题描述

我正在尝试使用 EditText 和 setSpan 在 Android 中实现一种简单的语法突出显示。从 TextWatcher 的 afterTextChanged 中调用语法高亮方法。为了有一个新的开始,我想在开始时清除所有跨度。但是,我只能输入一个字符。之后,该应用程序不再调用 afterTextChanged 并且似乎被卡住了。

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val editor: EditText = findViewById(R.id.sourceEditText)!!

        editor.addTextChangedListener(MyTextWatcher())
    }

    class MyTextWatcher(): TextWatcher {
        override fun afterTextChanged(s: Editable) {
            Log.d("MainActivity", "afterTextChanged");
            s.clearSpans()
            Log.d("MainActivity", "afterTextChanged end")
        }

        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
            Log.d("MainActivity", "beforeTextChanged")
        }

        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
            Log.d("MainActivity", "onTextChanged")
        }
    }
}

输入两个字符后的日志输出([编辑]仅显示第一个字符)是

2019-09-16 17:35:28.418 6231-6231/at.searles.sourceeditor D/MainActivity: beforeTextChanged
2019-09-16 17:35:28.419 6231-6231/at.searles.sourceeditor D/MainActivity: onTextChanged
2019-09-16 17:35:28.431 6231-6231/at.searles.sourceeditor D/MainActivity: afterTextChanged
2019-09-16 17:35:28.433 6231-6231/at.searles.sourceeditor D/MainActivity: afterTextChanged end

并且应用程序卡住了。

我正在使用 API 24/Android 7.0 在模拟器上进行测试

标签: androidkotlinandroid-edittext

解决方案


试试这个,而不是清除所有跨度,您只需要删除您添加的跨度类型:

class MainActivity : Activity() {

    lateinit var editor: EditText

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        editor = findViewById(R.id.sourceEditText)!!
        editor.addTextChangedListener(MyTextWatcher())
    }

    inner class MyTextWatcher() : TextWatcher {

        override fun afterTextChanged(s: Editable) {
            editor.removeTextChangedListener(this)
            val spans = s.getSpans(0, s.length, YourHighlightSpan::class.java)
            for (sp in spans) {
                s.removeSpan(sp)
            }
            editor.addTextChangedListener(this)
        }

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

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

推荐阅读