摘要:SpannableStringBuilder错误地使用InputFilter :: filter(...)的'end'参数来设置'source'的长度
背景
InputFilter有以下方法:
abstract CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
根据官方文件:
当缓冲区要替换范围时,将调用此方法 dstart ... dend of dest with the range from the range start ... end of 源。
我们感兴趣的参数是 end
支持证据:
1)robolectric单元测试(在实际的Android设备上测试时结果相同):
@RunWith(RobolectricTestRunner.class)
public class playground
{
static int mTestNumber; //so know which testcase is being run in filter();
@Test
public void test_SpannableStringBuilder()
{
SpannableStringBuilder ssb;
InputFilter inputFilter;
inputFilter = new InputFilter()
{
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
{
int[] expected,
results;
results= new int[] {start, end, dstart, dend};
switch (mTestNumber)
{
case 0: //"0123" appended to default initialization (empty string?)
expected= new int[] {0, 3, 0, 0};
Assert.assertArrayEquals(expected, results); // fails since end=4.
break;
}
return null;
}
};
mTestNumber= 0;
ssb= new SpannableStringBuilder(""); //internally stored as 2 chars" "0\0"
ssb.setFilters((new InputFilter[] {inputFilter}));
ssb.append("0123");
return;
}
} ///END CLASS///
(开始,结束)应为(0,3)
但是当测试运行时:
(开始,结束)=(0,4)
似乎 结束 返回长度
进一步挖掘:
在SpannableStringBuilder中查看:
SpannableStringBuilder append(CharSequence text)
替换的便利性(length(),length(),text,0,text.length())
然后
SpannableStringBuilder replace(int start, int end, CharSequence tb, int tbstart, int tbend)
使用a替换此Editable中文本的指定范围(st ... en) 切片的副本从源头开始...结束。
注意:
1)append()将text.length()放入tbend(我相信这是bug的来源)
2)replace()文档的参数名称错误
思想
这看起来是一个明显的错误,特别是因为除了最简单的情况之外,它基本上使InputFilter不能用EditText。我一直无法找到关于这个bug的任何信息。我很难相信它之前没有出现过。我在这里错过了什么吗?