public void setSpan (Object what, int start, int end, int flags)
Parámetro 1 qué: varios intervalos como tamaño de fuente, color de fuente, etc.
Parámetro 2 inicio: la posición de inicio del subíndice de carácter a modificar, la modificación incluirá la posición de inicio
Parámetro 2 fin: la posición final del subíndice del carácter a modificar, excluyendo el carácter en esta posición
Banderas del parámetro 2: Generalmente hay cuatro modos comunes, que se mencionarán a continuación. Esta bandera no tiene nada que ver con los dos primeros parámetros de inicio y fin, es decir
No se utiliza para controlar los dos primeros parámetros.
Aquí hay algunas situaciones que a menudo no están claras
1 problemas de inicio y finalización
No importa en qué modo establezca el parámetro de banderas, no afectará el inicio y el final. La posición donde cambia el carácter incluye la posición inicial pero no la posición final
Como se muestra en la figura: inicio: 1; final: 6. La fuente de los subíndices de caracteres [1] - [5] en la figura se vuelve más grande, no importa qué banderas sean, no afectará la posición de la fuente agrandada
La longitud de la cadena en la figura es 10 y el subíndice corresponde a [0] - [9]
Como se muestra en la figura start: 1; end: 10 La fuente de los subíndices de caracteres [1] - [9] en la figura se hace más grande
Pero si ingresa 11 al final, el programa se bloqueará y se producirá una excepción directamente. 10 también excede el subíndice de este carácter, ¿por qué 10 no sale mal?
Mira el código fuente:
/ * paquete * / void setSpan (Object what , int start , int end , int flags) { int nstart = start ; int nend = fin ; checkRange ( "setSpan" , inicio , final) ; // ① :检查 inicio 和 final 是否 符合 要求 if ((flags & Spannable. SPAN_PARAGRAPH ) == Spannable. SPAN_PARAGRAPH ) { if (start! = 0 && start! = Length ()) { char c = charAt (start - 1 ) ; if (c! = ' \ n ' ) throw new RuntimeException ( "El intervalo de PARAGRAPH debe comenzar en el límite del párrafo" + "(" + inicio + "sigue a" + c + ")" ) ; } if (end! = 0 && end! = length ()) { char c = charAt (end- 1 ) ; // ②: Mira esto y entenderás por qué no se incluye end si (c! = ' \ n ' ) throw new RuntimeException ( "El intervalo de PARAGRAPH debe terminar en el límite del párrafo" + "(" + end + "sigue a" + c + ")" ) ; } }
¿Cómo es el método checkRange (.....)?
private void checkRange(final String operation, int start, int end) { if (end < start) { throw new IndexOutOfBoundsException(operation + " " + region(start, end) + " has end before start"); } int len = length();//这个length就是所要操作的字符串长度,就不贴源码了 //通过比较end是否已超过字符串长度,若超过则抛出异常。 // 因为上方② 处会charAt(end - 1) if (start > len || end > len) { throw new IndexOutOfBoundsException(operation + " " + region(start, end) + " ends beyond length " + len); } if (start < 0 || end < 0) { throw new IndexOutOfBoundsException(operation + " " + region(start, end) + " starts before 0"); } }
2 flags到底是干什么用的
当你不是操作TextView而是EditText这种可以输入的文本的时候,flags就起作用了。
你已经将某段字符做出改变,而你在所改变内容前后输入新的内容时,就会根据flags有所变化。
直接放图 看了就更容易明白:
1 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 前后都不包含
图中字母a是改变字体大小后输入的,SPAN_EXCLUSIVE_EXCLUSIVE模式,大小不会发生改变。
2 Spanned.SPAN_EXCLUSIVE_INCLUSIVE 不包含前面 包含后面
如图 在改变字体大小后输入A, 前面A没有变大,后面的变大
3 Spanned.SPAN_INCLUSIVE_EXCLUSIVE 包含前面,不包含后面
4 Spanned.SPAN_INCLUSIVE_INCLUSIVE 前后都包含
总结一下,flags是对可以输入新文本的控件才会起作用,如果你是对TextView操作,flags用哪个都一样的。