Cómo implementar una lupa de texto

Prueba hacerlo con Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Obtén información para usar texto en Compose.

Disponible en Android 9 (nivel de API 28) y versiones posteriores, el widget de ampliación es una lupa virtual que muestra una copia ampliada de un objeto View seleccionado a través de un panel superpuesto que representa la lente. Esta función mejora la experiencia del usuario con respecto a la inserción y selección del texto. Cuando se aplica la lupa al texto, el usuario puede ubicar con precisión el cursor o los controladores de selección viendo el texto ampliado en un panel que sigue su dedo.

En la Figura 1, se muestra la manera en que la lupa facilita la selección del texto. Las APIs de la lupa no están vinculadas al texto, y puedes usar este widget en una variedad de casos de uso, como leer texto pequeño o ampliar nombres de lugares difíciles de ver en los mapas.

Una imagen que muestra cómo aparece la lupa después de tomar el controlador de selección correcto
Figura 1. Ampliación del texto. Cuando el usuario arrastra el controlador de selección correcto, se abre la lupa de forma emergente para ayudar con la posición exacta.

La lupa ya está integrada con los widgets de la plataforma, como TextView, EditText y WebView. Permite la manipulación de texto coherente en todas las apps. El widget incluye una API simple y se puede usar para ampliar cualquier View según el contexto de tu app.

Uso de la API

Puedes usar la lupa de forma programática en una vista arbitraria de la siguiente manera:

Kotlin

val view: View = findViewById(R.id.view)
val magnifier = Magnifier.Builder(view).build()
magnifier.show(view.width / 2.0f, view.height / 2.0f)

Java

View view = findViewById(R.id.view);
Magnifier magnifier = new Magnifier.Builder(view).build();
magnifier.show(view.getWidth() / 2, view.getHeight() / 2);

Si suponemos que la jerarquía de la vista tiene el primer diseño, la lupa se muestra en la pantalla y contiene una región centrada en las coordenadas proporcionadas dentro de la vista. El panel aparece sobre el punto central del contenido que se copia. La lupa permanece de manera indefinida hasta que el usuario la descarta.

En el siguiente fragmento de código, se muestra cómo cambiar el fondo de la vista ampliada:

Kotlin

view.setBackgroundColor(...)

Java

view.setBackgroundColor(...);

Si suponemos que el color de fondo es visible dentro de la lupa, el contenido de la lupa está inactivo, ya que todavía se muestra una región de la vista con el fondo anterior. Para actualizar el contenido, usa el update() método de la siguiente manera:

Kotlin

view.post { magnifier.update() }

Java

view.post(magnifier::update);

Cuando termines, cierra la lupa; para ello, llama al dismiss() método:

Kotlin

magnifier.dismiss()

Java

magnifier.dismiss();

Ampliación con la interacción del usuario

Un caso práctico común para la lupa es permitir que el usuario amplíe una región de la vista cuando la toca, como se muestra en la Figura 2.

Figura 2: La lupa sigue el tacto del usuario. Se aplica a un ViewGroup que contiene una `ImageView` a la izquierda y un TextView a la derecha.

Para lograrlo, actualiza la lupa según los eventos táctiles que reciba la vista de la siguiente manera:

Kotlin

imageView.setOnTouchListener { v, event ->
  when (event.actionMasked) {
    MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
      val viewPosition = IntArray(2)
      v.getLocationOnScreen(viewPosition)
      magnifier.show(event.rawX - viewPosition[0], event.rawY - viewPosition[1])
    }
    MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
      magnifier.dismiss()
    }
  }
  true
}

Java

imageView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                // Fall through.
            case MotionEvent.ACTION_MOVE: {
                final int[] viewPosition = new int[2];
                v.getLocationOnScreen(viewPosition);
                magnifier.show(event.getRawX() - viewPosition[0],
                               event.getRawY() - viewPosition[1]);
                break;
            }
            case MotionEvent.ACTION_CANCEL:
                // Fall through.
            case MotionEvent.ACTION_UP: {
                magnifier.dismiss();
            }
        }
        return true;
    }
});

Consideraciones adicionales para la ampliación del texto

Para los widgets de texto de la plataforma, es importante comprender los comportamientos específicos de la lupa y habilitarla para tu vista de texto personalizada de manera coherente en toda la plataforma de Android. Ten en cuenta lo siguiente:

  • La lupa se activa de inmediato cuando el usuario toma un controlador de inserción o selección.
  • La lupa sigue de forma fluida el dedo del usuario de forma horizontal, mientras que verticalmente queda fija en el centro de la línea de texto actual.
  • Cuando se mueve de forma horizontal, la lupa solo se desplaza entre los límites izquierdo y derecho de la línea actual. Además, cuando el tacto del usuario sale de estos límites y la distancia horizontal entre el tacto y el límite más cercano es mayor que la mitad del ancho original del contenido de la lupa, se descarta la lupa, ya que el cursor ya no es visible dentro de ella.
  • La lupa nunca se activa cuando la fuente del texto es demasiado grande. El texto se considera demasiado grande cuando la diferencia entre el descenso y el ascenso de la fuente es superior a la altura del contenido que cabe en la lupa. Activar la lupa en este caso no agrega valor.