好吧,我尝试构建一个富文本编辑器.
我有一些按钮来格式化我的可编辑文本(粗体,斜体,URL等).
我使用 Google keyboard启用了所有文本更正选项(设置>语言和输入>谷歌键盘>文本更正).
我有一些按钮来格式化我的可编辑文本(粗体,斜体,URL等).
我使用 Google keyboard启用了所有文本更正选项(设置>语言和输入>谷歌键盘>文本更正).
我做了以下事情:
在我的EditText中,我写了一些文字.
我选择它并使用SPAN_EXCLUSIVE_EXCLUSIVE(33)作为标志应用粗体.
好的,这是问题所在.我的大胆旗帜已经改变……为什么!?
这是一些日志:
D/ContentUtils: beforeTextChanged: start end span flags D/ContentUtils: beforeTextChanged: 0 7 ChangeWatcher 8388626 D/ContentUtils: beforeTextChanged: 0 7 ChangeWatcher 6553618 D/ContentUtils: beforeTextChanged: 0 7 TextKeyListener 18 D/ContentUtils: beforeTextChanged: 0 7 SpanController 18 D/ContentUtils: beforeTextChanged: 7 7 START 546 D/ContentUtils: beforeTextChanged: 7 7 END 34 D/ContentUtils: beforeTextChanged: 0 7 SpellCheckSpan 33 D/ContentUtils: beforeTextChanged: 0 7 CustomBoldSpan 33 D/ContentUtils: onTextChaghed D/ContentUtils: onTextChaghed: 0 8 ChangeWatcher 8392722 D/ContentUtils: onTextChaghed: 0 8 ChangeWatcher 6557714 D/ContentUtils: onTextChaghed: 0 8 TextKeyListener 4114 D/ContentUtils: onTextChaghed: 0 8 SpanController 4114 D/ContentUtils: onTextChaghed: 8 8 START 546 D/ContentUtils: onTextChaghed: 8 8 END 34 D/ContentUtils: onTextChaghed: 0 8 CustomBoldSpan 4129 D/ContentUtils: onTextChaghed: 0 8 UnderlineSpan 289 D/ContentUtils: onTextChaghed: 0 8 ComposingText 289 D/ContentUtils: afterTextChanged D/ContentUtils: afterTextChanged: 0 8 ChangeWatcher 8392722 D/ContentUtils: afterTextChanged: 0 8 ChangeWatcher 6557714 D/ContentUtils: afterTextChanged: 0 8 TextKeyListener 4114 D/ContentUtils: afterTextChanged: 0 8 SpanController 4114 D/ContentUtils: afterTextChanged: 8 8 START 546 D/ContentUtils: afterTextChanged: 8 8 END 34 D/ContentUtils: afterTextChanged: 0 8 CustomBoldSpan 4129 D/ContentUtils: afterTextChanged: 0 8 UnderlineSpan 289 D/ContentUtils: afterTextChanged: 0 8 ComposingText 289 D/ContentUtils: afterTextChanged: 0 8 SpellCheckSpan 33
当我使用另一个键盘时,一切都很好.
当我禁用文本修正设置时,一切都很顺利.
我的所有范围都是自定义范围,并且是现有Android范围的子类.
解决方法
好吧,经过一些研究,似乎键盘在输入时会在一个单词周围应用一些跨度以便管理建议.
问题是针对每个打字的字母,该字词被删除并添加回添加的字母.在这一点上,我松开了一些自定义跨度,就像在单词中间那些.
如果你将TextWatcher添加到EditText,它将被调用2次:首先添加字母,第二次删除后添加回整个单词.根本不方便.
因此,一个丑陋的解决方案是在beforeTextChanged()期间复制所有跨度,并在第二个afterTextChanged()期间应用.但实施起来很复杂.
无论如何,其他应用程序没有做得更好:GMail和Evernote有同样的问题.我选择不担心,不应用丑陋的解决方案.我的富文本编辑器可以像这样使用……