Cómo implementar una lupa de texto

Prueba el estilo de Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Aprende a usar texto en Compose.

Disponible en Android 9 (nivel de API 28) y versiones posteriores, el widget de lupa es una lupa virtual que muestra una copia ampliada de un View a través de un panel superpuesto que representa la lente. La función mejora la experiencia del usuario para la inserción y selección de texto. Al aplicar la lupa al texto, el usuario puede colocar el cursor o los controladores de selección de manera precisa. Para ello, debe ver el texto ampliado en un panel que siga el dedo.

En la Figura 1, se muestra cómo la lupa facilita la selección del texto. Las APIs de 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 agarrar 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 para ayudar con la ubicación precisa.

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 aplicaciones. El widget incluye una API simple y se puede usar para ampliar cualquier View según el contexto de la app.

Uso de la API

Puedes usar la lupa de manera 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 vistas tiene el primer diseño, la lupa se muestra en la pantalla y contiene una región centrada en las coordenadas dadas dentro de la vista. El panel aparece sobre el punto central del contenido que se está copiando. La lupa persiste indefinidamente 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, su contenido estará inactivo, ya que es una región de la vista que aún muestra el fondo anterior. Para actualizar el contenido, usa el método update() de la siguiente manera:

Kotlin

view.post { magnifier.update() }

Java

view.post(magnifier::update);

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

Kotlin

magnifier.dismiss()

Java

magnifier.dismiss();

Ampliación con la interacción del usuario

Un caso de uso 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 una TextView a la derecha.

Para ello, 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 se 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 toque del usuario sale de estos límites y la distancia horizontal entre el toque y el límite más cercano es mayor que la mitad del ancho original del contenido de la lupa, esta se descarta, ya que el cursor ya no es visible dentro de la lupa.
  • 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 mayor que la altura del contenido que cabe en la lupa. En este caso, activar la lupa no agrega valor.