Implementar uma lupa de texto

Experimente trabalhar com o Compose
O Jetpack Compose é o kit de ferramentas de UI recomendado para Android. Aprenda a usar texto no Compose.

Disponível no Android 9 (nível da API 28) e versões mais recentes, o widget de lupa é uma lupa virtual que exibe uma cópia ampliada de um View por meio de um painel de sobreposição que representa a lente. O recurso melhora a experiência do usuário na inserção e seleção de texto. Ao aplicar a lupa ao texto, o usuário pode posicionar com precisão o cursor ou as alças de seleção visualizando o texto ampliado em um painel que acompanha o dedo.

A Figura 1 mostra como a lupa facilita a seleção de texto. As APIs de lupa não estão vinculadas ao texto, e você pode usar esse widget em vários casos de uso, como ler um texto pequeno ou aumentar os nomes de lugares difíceis de enxergar em mapas.

Uma imagem mostrando como a lupa aparece depois de segurar a alça de seleção da direita
Figura 1. Texto ampliado. Quando o usuário arrasta a alça de seleção da direita, a lupa aparece para ajudar no posicionamento preciso.

A lupa já está integrada aos widgets da plataforma, como TextView, EditText e WebView. Ela fornece uma manipulação de texto consistente em todos os apps. O widget vem com uma API simples e pode ser usado para ampliar qualquer View dependendo do contexto do seu app.

Uso da API

É possível usar a lupa de forma programática em uma visualização arbitrária da seguinte maneira:

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

Partindo do princípio de que a hierarquia de visualização já tinha o primeiro layout, a lupa é exibida na tela, contendo uma região centralizada nas coordenadas especificadas na visualização. O painel aparece acima do ponto central do conteúdo que está sendo copiado. A lupa persiste indefinidamente até o usuário dispensá-la.

O snippet de código a seguir mostra como mudar o plano de fundo da visualização ampliada:

Kotlin

view.setBackgroundColor(...)

Java

view.setBackgroundColor(...);

Presumindo que a cor do plano de fundo fica visível na lupa, o conteúdo da lupa está desatualizado, porque uma região da visualização com o plano de fundo antigo ainda é exibida. Para atualizar o conteúdo, use o método update() da seguinte maneira:

Kotlin

view.post { magnifier.update() }

Java

view.post(magnifier::update);

Ao terminar, feche a lupa chamando o método dismiss():

Kotlin

magnifier.dismiss()

Java

magnifier.dismiss();

Ampliar com a interação do usuário

Um caso de uso comum para a lupa é permitir que o usuário amplie uma região de visualização tocando nela, conforme mostrado na figura 2.

Figura 2. A lupa segue o toque do usuário. Ela é aplicada a um ViewGroup que contém um `ImageView` à esquerda e um TextView à direita.

Para fazer isso, atualize a lupa de acordo com os eventos de toque recebidos pela visualização, da seguinte forma:

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

Considerações adicionais ao ampliar texto

Para os widgets de texto da plataforma, é importante entender os comportamentos específicos da lupa e ativá-la para a visualização de texto personalizada de forma consistente em toda a plataforma Android. Considere o seguinte:

  • A lupa é acionada imediatamente quando o usuário segura uma alça de inserção ou seleção.
  • A lupa sempre segue o dedo do usuário na horizontal suavemente, enquanto na vertical ela é fixada no centro da linha de texto atual.
  • Ao mover-se horizontalmente, a lupa se move somente entre os limites esquerdo e direito da linha atual. Além disso, quando o usuário deixa esses limites e a distância horizontal entre o toque e o limite mais próximo é maior do que a metade da largura original do conteúdo da lupa, a lupa é dispensada, porque o cursor não fica mais visível dentro dela.
  • A lupa nunca é acionada quando a fonte do texto é muito grande. O texto é considerado muito grande quando a diferença entre o descendente e o ascendente da fonte é maior do que a altura do conteúdo que cabe na lupa. O acionamento da lupa, nesse caso, não agrega valor.