Implementare una lente d'ingrandimento

Prova Compose
Jetpack Compose è il toolkit per la UI consigliato per Android. Scopri come utilizzare il testo in Crea.

Disponibile in Android 9 (livello API 28) e versioni successive, il widget Lente d'ingrandimento è una lente d'ingrandimento virtuale che mostra una copia ingrandita di un View tramite un riquadro di overlay che rappresenta la lente. La funzionalità migliora l'esperienza utente di inserimento e selezione del testo. Quando applica la lente d'ingrandimento al testo, un utente può posizionare con precisione il cursore o i punti di manipolazione della selezione visualizzando il testo ingrandito in un riquadro che segue il dito.

La figura 1 mostra come la lente di ingrandimento facilita la selezione del testo. Le API di ingrandimento non sono associate al testo e puoi utilizzare questo widget in una serie di casi d'uso, ad esempio per leggere testi piccoli o ingrandire i nomi di luoghi difficili da vedere sulle mappe.

Un'immagine che mostra come appare la lente d'ingrandimento dopo aver afferrato il punto di manipolazione di selezione a destra
Figura 1. Ingrandimento del testo. Quando l'utente trascina il punto di manipolazione di selezione a destra, viene visualizzata la lente d'ingrandimento per facilitare il posizionamento preciso.

La lente d'ingrandimento è già integrata con i widget della piattaforma come TextView, EditText e WebView. Consente di manipolare il testo in modo coerente tra le app. Il widget è dotato di un'API semplice e può essere utilizzato per ingrandire qualsiasi View a seconda del contesto dell'app.

Utilizzo delle API

Puoi utilizzare la lente d'ingrandimento a livello di programmazione su una visualizzazione arbitraria nel seguente modo:

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);

Supponendo che la gerarchia delle visualizzazioni abbia il primo layout, la lente di ingrandimento viene visualizzata sullo schermo e contiene una regione centrata sulle coordinate specificate all'interno della visualizzazione. Il riquadro viene visualizzato sopra il punto centrale dei contenuti copiati. La lente di ingrandimento rimane visualizzata a tempo indeterminato finché l'utente non la chiude.

Il seguente snippet di codice mostra come modificare lo sfondo della visualizzazione ingrandita:

Kotlin

view.setBackgroundColor(...)

Java

view.setBackgroundColor(...);

Supponendo che il colore di sfondo sia visibile all'interno della lente d'ingrandimento, il contenuto della lente d'ingrandimento è obsoleto, in quanto viene ancora visualizzata una regione della visualizzazione con il vecchio sfondo. Per aggiornare i contenuti, utilizza il metodo update() come segue:

Kotlin

view.post { magnifier.update() }

Java

view.post(magnifier::update);

Al termine, chiudi la lente d'ingrandimento chiamando il metodo dismiss():

Kotlin

magnifier.dismiss()

Java

magnifier.dismiss();

Ingrandimento in base all'interazione dell'utente

Un caso d'uso comune della lente di ingrandimento è consentire all'utente di ingrandire una regione di visualizzazione toccandola, come mostrato nella figura 2.

Figura 2. La lente d'ingrandimento segue il tocco dell'utente. Viene applicato a un ViewGroup che contiene un `ImageView` a sinistra e un TextView a destra.

Puoi farlo aggiornando la lente d'ingrandimento in base agli eventi tocco ricevuti dalla visualizzazione, come segue:

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;
    }
});

Ulteriori considerazioni quando si ingrandisce il testo

Per i widget di testo della piattaforma, è importante comprendere i comportamenti specifici della lente d'ingrandimento e attivarla per la visualizzazione testo personalizzata in modo coerente sulla piattaforma Android. Considera quanto segue:

  • La lente d'ingrandimento si attiva immediatamente quando l'utente afferra un handle di inserimento o selezione.
  • La lente d'ingrandimento segue sempre il dito dell'utente in orizzontale, mentre in verticale è fissa al centro della riga di testo corrente.
  • Quando ti sposti orizzontalmente, la lente d'ingrandimento si muove solo tra i limiti sinistro e destro della riga corrente. Inoltre, quando il tocco dell'utente esce da questi limiti e la distanza orizzontale tra il tocco e il limite più vicino è maggiore della metà della larghezza originale dei contenuti dell'ingranditore, l'ingranditore viene chiuso, poiché il cursore non è più visibile al suo interno.
  • La lente d'ingrandimento non viene mai attivata quando il carattere del testo è troppo grande. Il testo è considerato troppo grande quando la differenza tra la discesa e l'altezza del carattere è maggiore dell'altezza dei contenuti che rientrano nella lente d'ingrandimento. L'attivazione della lente d'ingrandimento in questo caso non aggiunge valore.