Editores de texto personalizados

Editores de texto personalizados são visualizações que não são EditText ou WebView widgets de texto, mas mas oferecer suporte à entrada de texto implementando onCreateInputConnection() callback, que é chamado quando uma visualização está em foco e o sistema solicita uma InputConnection para a visualização.

Uma chamada para onCheckIsTextEditor() de um editor de texto personalizado deve retornar true.

Suporte à escrita à mão com stylus em editores de texto personalizados

O Android 14 (nível 34 da API) e versões mais recentes oferecem suporte à entrada com stylus no Android padrão componentes de entrada de texto por padrão (consulte Entrada de stylus em texto) campos). No entanto, os campos de entrada de texto personalizados (ou editores) exigem desenvolvimento adicional.

Para criar um editor de texto personalizado, faça o seguinte:

  1. Ativar iniciação de escrita à mão
  2. Declarar compatibilidade com escrita à mão
  3. Oferecer suporte a gestos de escrita à mão (selecionar, excluir, inserir e assim por diante)
  4. Fornecer o local do cursor e outros dados de posição ao IME
  5. Mostrar o ícone de passar o cursor sobre a escrita à mão com a stylus

Ativar iniciação de escrita à mão

Se uma visualização consistir apenas em um único editor de texto, o sistema de visualização poderá iniciar automaticamente a escrita à mão com a stylus para a visualização. Caso contrário, a visualização precisará implementar sua própria lógica de iniciação de escrita à mão.

Iniciação automática de escrita à mão

Se uma visualização tiver apenas um editor de texto e nenhum outro conteúdo, ela poderá ativar para a iniciação automática de escrita à mão do sistema de visualização chamando setAutoHandwritingEnabled(true)

Com a escrita automática à mão ativada, o movimento da stylus começa em qualquer lugar da visualização limites de escrita à mão iniciam o modo de escrita à mão automaticamente. Método de entrada editor (IME) recebe os eventos de movimento da stylus e confirma o texto reconhecido.

Campo de entrada com um retângulo ao redor indicando os limites para a detecção de eventos de movimento da stylus.
Figura 1. Escrita à mão nos limites de um campo EditText.

Iniciação de escrita à mão personalizada

Se uma visualização tiver vários editores de texto ou conteúdo, além de um único texto a visualização precisa implementar sua própria lógica de iniciação de escrita à mão, da seguinte maneira:

  1. Desative a iniciação automática de escrita à mão do sistema de visualização chamando setAutoHandwritingEnabled(false)

  2. Acompanhe todos os editores de texto visíveis na visualização.

  3. Monitore eventos de movimento recebidos pela visualização no dispatchTouchEvent()

    • Quando o movimento da stylus ocorre dentro dos limites de escrita à mão de um editor de texto, focar no editor de texto (se ele ainda não estiver em foco).

    • Se o editor ainda não estava em foco, reinicie o IME do editor com as novas conteúdos chamando InputMethodManager#restartInput()

    • Inicie a sessão de escrita à mão com a stylus chamando InputMethodManager#startStylusHandwriting()

.

Se um editor de texto estiver dentro de uma visualização rolável, o movimento da stylus dentro da os limites de escrita à mão do editor devem ser considerados texto manuscrito, não de rolagem. Usar ViewParent#requestDisallowInterceptTouchEvent() para evitar que uma visualização de ancestral rolável intercepte eventos de toque de um texto editor.

Detalhes da API

  • MotionEvent#getToolType() — Indica se o MotionEvent é de uma stylus. Nesse caso, o valor de retorno é TOOL_TYPE_STYLUS ou TOOL_TYPE_ERASER

  • InputMethodManager#isStylusHandwritingAvailable() — Indica se o IME é compatível com escrita à mão com stylus. Chamar este antes de cada chamada para InputMethodManager#startStylusHandwriting() já que a disponibilidade da escrita pode ter mudado.

  • InputMethodManager#startStylusHandwriting() : faz com que o IME entre no modo de escrita à mão. Um ACTION_CANCEL de movimento é enviado ao app para cancelar o gesto atual. Stylus eventos de movimento não são mais enviados para o app.

    Eventos de movimento da stylus do gesto atual que já foram enviados para e o aplicativo são encaminhados para o IME. O IME é necessário para mostrar uma tinta stylus Janela pela qual o IME recebe todos os objetos MotionEvent a seguir. O IME confirma o texto escrito à mão reconhecido usando o InputConnection APIs de terceiros.

    Se o IME não puder entrar no modo de escrita à mão, essa chamada de método será um ambiente autônomo.

Declarar compatibilidade com escrita à mão

Ao preencher Argumento EditorInfo de Chamada do View#onCreateInputConnection(EditorInfo) setStylusHandwritingEnabled() para informar ao IME que o editor de texto é compatível com a escrita à mão. Declare gestos compatíveis com setSupportedHandwritingGestures() e setSupportedHandwritingGesturePreviews()

Suporte a gestos de escrita à mão

Os IMEs (editores de método de entrada, na sigla em inglês) são compatíveis com vários gestos de escrita à mão, como circular o texto para seleção. ou rabiscar o texto para excluí-lo.

Figura 2. Circule para selecionar o texto.
.
.
Figura 3. Rabisque para excluir texto.

Implementação dos editores personalizados InputConnection#performHandwritingGesture() e InputConnection#previewHandwritingGesture() para dar suporte a diferentes HandwritingGesture tipos, como SelectGesture, DeleteGesture e InsertGesture.

Declarar gestos de escrita à mão com suporte ao preencher o argumento EditorInfo de View#onCreateInputConnection(EditorInfo) (consulte a seção Declarar escrita à mão suporte).

Detalhes da API

  • InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer) : implementa gestos. O argumento HandwritingGesture contém de localização que você pode usar para determinar em que parte do texto realizar o gesto. Por exemplo, SelectGesture fornece uma objeto RectF que especifica o intervalo de texto selecionado, e InsertGesture fornece um PointF que especifica o deslocamento no qual o texto deve ser inserido.

    Use as APIs Executor e IntConsumer parâmetros para retornar o resultado da operação. Quando o executor e argumentos do consumidor forem fornecidos, use o executor para chamar IntConsumer#accept(), Por exemplo:

    
    executor.execute { consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS) }
    
    
  • HandwritingGesture#getFallbackText() : fornece o texto substituto que o IME confirma na posição do cursor se não o texto aplicável está abaixo da área de um gesto de escrita à mão.

    Às vezes, o IME não consegue determinar se um gesto da stylus é destinada a realizar uma operação de gesto ou escrever texto à mão. Um texto personalizado é responsável por determinar a intenção do usuário e realizar a ação adequada (dependendo do contexto) no local do gesto.

    Por exemplo, se o IME não puder determinar se o usuário pretendia desenhar um acento circunflexo para baixo ⋁ para inserir um espaço ou escrever à mão o a letra "v", o IME poderá enviar uma InsertGesture com o texto substituto "v".

    Primeiro, o editor precisa tentar executar o gesto de inserir espaço. Se o o gesto não pode ser realizado (por exemplo, não há texto no local especificado), o editor voltará a inserir o "v" no cursor posição

  • InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal) - Visualiza um gesto em andamento. Por exemplo, quando o usuário começa a desenhar um círculo ao redor de um texto, uma visualização dinâmica da seleção resultante pode ser mostrados e atualizados continuamente à medida que o usuário continua desenhando. Apenas algumas de gestos são visualizáveis (consulte PreviewableHandwritingGesture).

    O parâmetro CancellationSignal pode ser usado pelo IME para cancelar o prévia. Se outros eventos interromperem a visualização (por exemplo, o texto for alterado programaticamente ou novos comandos InputConnection), o editor personalizado para cancelar a visualização.

    Os gestos de visualização são apenas para exibição e não podem mudar estado. Por exemplo, uma visualização SelectGesture oculta a interface atual do editor intervalo de seleção e destaca o intervalo da visualização de gestos. Mas, uma vez visualização for cancelada, o editor deverá restaurar o intervalo de seleção anterior.

Fornecer a localização do cursor e outros dados de posição

No modo de escrita à mão, o IME pode solicitar a localização do cursor e outros dados de posição. usando InputConnection#requestCursorUpdates() O editor personalizado responde com uma chamada InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo) Os dados no CursorAnchorInfo relevantes para escrita à mão com stylus são fornecidos pelas seguintes opções: CursorAnchorInfo.Builder métodos:

  • setInsertionMarkerLocation() : define a localização do cursor. O IME usa o valor para animar escrita à mão até a posição do cursor.
  • setEditorBoundsInfo() : define os limites do editor e de escrita à mão. O IME usa esses dados para posicionar a barra de ferramentas de escrita à mão do IME na tela.
  • addVisibleLineBounds() — Define os limites de todas as linhas de texto visíveis (ou parcialmente visíveis) de o editor. O IME usa os limites de linha para melhorar a precisão no reconhecimento gestos de escrita à mão.
  • setTextAppearanceInfo() — define a aparência do texto com informações derivadas do texto campo de entrada. O IME usa as informações para estilizar a tinta da escrita à mão.

Mostrar o ícone de passar o cursor sobre a escrita à mão com a stylus

Mostrar o ícone de passar o cursor sobre a stylus de escrita à mão limites de escrita à mão do editor de texto personalizado e o IME selecionado oferece suporte escrita à mão com stylus (InputMethodManager#isStylusHandwritingAvailable()).

Substituir View#onResolvePointerIcon() para ver um ícone de passar o cursor para escrever à mão com a stylus. Na substituição, chame PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING) para acessar o ícone de passar o cursor sobre a escrita à mão do sistema.

Outros recursos