Android TextView:为何仅append()会触发newEditable()而非setText()?
这个问题得从TextView内部处理文本的逻辑入手,咱们掰碎了说:
1. setText()的核心逻辑
当你调用setText("some text")时,TextView默认走的是BufferType.NORMAL模式。在这个模式下,TextView会直接复用你传入的CharSequence实例(这里就是普通的String对象)作为内部存储的文本,完全不需要把它转换成Editable类型。
只有两种情况setText才会触发Editable.Factory的调用:
- 你明确指定了
BufferType.EDITABLE,比如调用setText("text", TextView.BufferType.EDITABLE) - 当前TextView本身是可编辑状态(比如EditText这种继承自TextView的可编辑控件)
2. append()的核心逻辑
append()方法的本质是对现有文本进行追加修改,而这种修改操作必须依赖可编辑的Editable类型才能完成。
所以当你第一次调用append时,如果TextView当前的内部文本还不是Editable(比如之前用setText设置了普通String),TextView会先调用Editable.Factory.newEditable(),把原有文本转换成Editable对象替换掉原来的内容,之后才会执行追加操作——这就是为什么你的newEditable回调会被触发。
举个简单的验证例子:如果先调用setText("init text", TextView.BufferType.EDITABLE),之后再调用普通的setText("new text"),这时候setText也不会触发newEditable。因为此时虽然内部文本是Editable,但setText在NORMAL模式下会直接把传入的String内容覆盖到已有的Editable对象里,不会重新创建新的Editable实例,自然就不会调用你的回调方法。
简单总结:append必须依赖Editable来完成追加动作,所以会主动触发Editable的创建;而setText在默认模式下可以用不可变的CharSequence,不需要创建新的Editable,因此不会触发你的Factory回调。
内容的提问来源于stack exchange,提问作者Toni Joe

