java android word-wrap breakiterator

java - ¿Cómo funciona BreakIterator en Android?



word-wrap (1)

Estoy haciendo mi propio procesador de texto en Android (un script vertical personalizado TextView para mongol). Pensé que tendría que encontrar todas las ubicaciones de BreakIterator línea para poder implementar el BreakIterator línea, pero luego descubrí BreakIterator . Esto parece encontrar todos los saltos posibles entre caracteres, palabras, líneas y oraciones en varios idiomas.

Estoy tratando de aprender cómo usarlo. La BreakIterator fue más útil que el promedio, pero aún así fue difícil de entender simplemente leyendo. También encontré algunos tutoriales (ver here , here y here ) pero carecían de la explicación completa con la salida que estaba buscando.

Estoy agregando esta respuesta de estilo de preguntas y respuestas para ayudarme a aprender cómo usar BreakIterator .

Estoy haciendo de esto una etiqueta de Android además de Java porque aparentemente hay alguna diferencia entre ellos. Además, Android ahora es compatible con el ICU BreakIterator y las futuras respuestas pueden abordar esto.


BreakIterator se puede utilizar para encontrar los posibles saltos entre caracteres, palabras, líneas y oraciones. Esto es útil para cosas como mover el cursor a través de caracteres visibles, hacer doble clic para seleccionar palabras, hacer triple clic para seleccionar oraciones y ajustar líneas.

Código repetitivo

El siguiente código se utiliza en los ejemplos a continuación. Simplemente ajuste la primera parte para cambiar el texto y el tipo de BreakIterator .

// change these two lines for the following examples String text = "This is some text."; BreakIterator boundary = BreakIterator.getCharacterInstance(); // boiler plate code boundary.setText(text); int start = boundary.first(); for (int end = boundary.next(); end != BreakIterator.DONE; end = boundary.next()) { System.out.println(start + " " + text.substring(start, end)); start = end; }

Si solo quiere probar esto, puede pegarlo directamente en una actividad onCreate en Android. Estoy usando System.out.println lugar de Log para que también sea comprobable en un entorno solo de Java.

Estoy usando el java.text.BreakIterator lugar del ICU, que solo está disponible desde la API 24. Consulte los enlaces en la parte inferior para obtener más información.

Caracteres

Cambie el código repetitivo para incluir lo siguiente

String text = "Hi 中文éé/uD83D/uDE00/uD83C/uDDEE/uD83C/uDDF3."; BreakIterator breakIterator = BreakIterator.getCharacterInstance();

Salida

0 H 1 i 2 3 中 4 文 5 é 6 é 8 😀 10 🇮🇳 14 .

Las partes más interesantes están en los índices 6 , 8 y 10 . Es posible que su navegador muestre o no los caracteres correctamente, pero un usuario interpretaría que todos estos son caracteres individuales a pesar de que están formados por múltiples valores UTF-16.

Palabras

Cambie el código repetitivo para incluir lo siguiente:

String text = "I like to eat apples. 我喜欢吃苹果。"; BreakIterator boundary = BreakIterator.getWordInstance();

Salida

0 I 1 2 like 6 7 to 9 10 eat 13 14 apples 20 . 21 22 我 23 喜欢 25 吃 26 苹果 28 。

Hay algunas cosas interesantes para tener en cuenta aquí. Primero, se detecta un salto de palabra a ambos lados de un espacio. En segundo lugar, a pesar de que existen diferentes idiomas, aún se reconocieron las palabras chinas de varios caracteres. Esto todavía era cierto en mis pruebas incluso cuando configuré la configuración regional en Locale.US .

Líneas

Puede mantener el código igual que para el ejemplo de palabras:

String text = "I like to eat apples. 我喜欢吃苹果。"; BreakIterator boundary = BreakIterator.getLineInstance();

Salida

0 I 2 like 7 to 10 eat 14 apples. 22 我 23 喜 24 欢 25 吃 26 苹 27 果。

Tenga en cuenta que las ubicaciones de ruptura no son líneas completas de texto. Son solo lugares convenientes para el texto de ajuste de línea.

El resultado es similar al ejemplo de palabras. Sin embargo, ahora el espacio en blanco y la puntuación se incluyen con la palabra anterior. Esto tiene sentido porque no desea que una nueva línea comience con espacios en blanco o signos de puntuación. También tenga en cuenta que los caracteres chinos obtienen saltos de línea para cada carácter. Esto es consistente con el hecho de que está bien dividir palabras de varios caracteres entre líneas en chino.

Frases

Cambie el código repetitivo para incluir lo siguiente:

String text = "I like to eat apples. My email is [email protected]./n" + "This is a new paragraph. 我喜欢吃苹果。我不爱吃臭豆腐。"; BreakIterator boundary = BreakIterator.getSentenceInstance();

Salida

0 I like to eat apples. 22 My email is [email protected]. 50 This is a new paragraph. 75 我喜欢吃苹果。 82 我不爱吃臭豆腐。

Los saltos de oración correctos se reconocieron en varios idiomas. Además, no hubo falsos positivos para el punto en el dominio de correo electrónico.

Notas

Puede establecer la configuración Locale cuando crea un BreakIterator , pero si no lo hace, solo usa la configuración regional predeterminada .

Otras lecturas