Pregunta

Tengo un TextView con un OnTouchListener. Lo que quiero es el índice de caracteres que el usuario está apuntando a cuando llegue el MotionEvent. ¿Hay alguna manera de llegar a las medidas de fuente subyacentes de la TextView?

¿Fue útil?

Solución

No soy consciente de una forma sencilla y directa de hacer esto, pero usted debe ser capaz de poner algo juntos utilizando la Paint objeto de la TextView través de una llamada a TextView.getPaint ()

Una vez que tenga el objeto pintura tendrá acceso a los FontMetrices subyacentes a través de una llamada a Paint.getFontMetrics () y tener acceso a otras funciones como Paint.measureText () Paint.getTextBounds (), y Paint.getTextWidths () para acceder al tamaño real del texto que se muestra.

Otros consejos

¿Usted ha intentado algo como esto:

Layout layout = this.getLayout();
if (layout != null)
{
    int line = layout.getLineForVertical(y);
    int offset = layout.getOffsetForHorizontal(line, x);

    // At this point, "offset" should be what you want - the character index
}

Espero que esto ayude ...

A pesar de que generalmente funciona tuve algunos problemas con la respuesta de Tony Blues.

En primer lugar vuelve getOffsetForHorizontal un desplazamiento, incluso si la coordenada x es mucho más allá del último carácter de la línea.

En segundo lugar el desplazamiento en ocasiones de carácter devuelto pertenece al siguiente carácter, no el carácter directamente debajo del puntero. Al parecer, el método devuelve el desplazamiento de la posición del cursor más cercano. Esto puede ser a la izquierda oa la derecha del carácter dependiendo de lo que está más cerca.

Mi solución utiliza getPrimaryHorizontal lugar a determinar la posición del cursor de un determinado offset y usos de búsqueda binaria para encontrar el desplazamiento debajo del puntero coordenada x.

public static int getCharacterOffset(TextView textView, int x, int y) {
    x += textView.getScrollX() - textView.getTotalPaddingLeft();
    y += textView.getScrollY() - textView.getTotalPaddingTop();

    final Layout layout = textView.getLayout();

    final int lineCount = layout.getLineCount();
    if (lineCount == 0 || y < layout.getLineTop(0) || y >= layout.getLineBottom(lineCount - 1))
        return -1;

    final int line = layout.getLineForVertical(y);
    if (x < layout.getLineLeft(line) || x >= layout.getLineRight(line))
        return -1;

    int start = layout.getLineStart(line);
    int end = layout.getLineEnd(line);

    while (end > start + 1) {
        int middle = start + (end - start) / 2;

        if (x >= layout.getPrimaryHorizontal(middle)) {
            start = middle;
        }
        else {
            end = middle;
        }
    }

    return start;
}

Editar:. Esta versión actualizada funciona mejor con saltos de línea no natural, cuando una palabra larga no cabe en una línea y se pone en algún lugar en medio de división

Advertencias: En los textos dividir con guión, hacer clic en el guión al final de una línea de devolver el índice del carácter al lado de él. Además, este método no funciona bien con textos RTL.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top