Um Editor de método de entrada (IME) é um controle de usuário que permite que os usuários insiram texto. O Android oferece um framework de método de entrada extensível que permite que os aplicativos forneçam aos usuários métodos de entrada alternativos, como teclado na tela ou entrada de fala. Depois de instalar os IMEs, o usuário pode selecionar um as configurações do sistema e usá-las em todo o sistema. Somente um IME pode ser ativado por vez.
Para adicionar um IME ao sistema Android, crie um aplicativo Android contendo uma classe que
estende
InputMethodService
:
Além disso, você geralmente cria uma "configuração" atividade que transmite opções para o serviço IME. Você
também pode definir uma IU de configurações que é exibida como parte das configurações do sistema.
Nesta página, abordamos os seguintes tópicos:
- Ciclo de vida do IME
- Como declarar componentes do IME no manifesto do app
- API IME
- Como projetar uma interface do IME
- Como enviar texto de um IME para um aplicativo
- Como trabalhar com subtipos de IME
- Outras considerações sobre o IME
Se você ainda não trabalhou com IMEs, leia o artigo introdutório Métodos de entrada na tela primeiro.
O ciclo de vida do IME
O diagrama a seguir descreve o ciclo de vida de um IME:
As seções a seguir descrevem como implementar a interface e o código associado a um IME que segue esse ciclo de vida.
Declarar os componentes do IME no manifesto
No sistema Android, um IME é um aplicativo para Android que contém um serviço de IME especial. A
arquivo de manifesto do aplicativo deve declarar o serviço, solicitar as permissões necessárias, fornecer uma
filtro de intent que corresponde à ação action.view.InputMethod
e fornecem metadados
que define as características do IME. Além disso, para fornecer uma interface de configurações que permite que o
o usuário modificar o comportamento do IME, poderá definir uma "configurações" que pode ser iniciada
Configurações do sistema.
O snippet a seguir declara um serviço de IME. Ele solicita a permissão
BIND_INPUT_METHOD
para permitir que o serviço conecte o IME (editor de método de entrada, na sigla em inglês) ao sistema, configura um filtro de intent que corresponda à ação
android.view.InputMethod
e define metadados para o IME:
<!-- Declares the input method service. --> <service android:name="FastInputIME" android:label="@string/fast_input_label" android:permission="android.permission.BIND_INPUT_METHOD"> <intent-filter> <action android:name="android.view.InputMethod" /> </intent-filter> <meta-data android:name="android.view.im" android:resource="@xml/method" /> </service>
O snippet a seguir declara a atividade de configurações do IME. Ele tem um filtro de intent para
ACTION_MAIN
que
indica que essa atividade é o ponto de entrada principal para o aplicativo IME:
<!-- Optional: an activity for controlling the IME settings. --> <activity android:name="FastInputIMESettings" android:label="@string/fast_input_settings"> <intent-filter> <action android:name="android.intent.action.MAIN"/> </intent-filter> </activity>
Você também pode fornecer acesso às configurações do IME diretamente de sua interface.
A API do método de entrada
Classes específicas para IMEs são encontradas na
android.inputmethodservice
e
android.view.inputmethod
pacotes. A classe KeyEvent
é
importante para lidar com caracteres do teclado.
A parte central de um IME é um componente de serviço, uma classe que estende
InputMethodService
: Além de implementar o ciclo de vida normal do serviço, esse
tem callbacks para fornecer a interface do usuário do IME, lidar com a entrada do usuário e enviar texto ao
em foco. Por padrão, a classe InputMethodService
fornece a maior parte dos
implementação para gerenciar o estado e a visibilidade do IME e se comunicar com o servidor
campo de entrada.
As seguintes classes também são importantes:
BaseInputConnection
-
Define o canal de comunicação de uma
InputMethod
ao aplicativo que está recebendo a entrada. Você pode usá-lo para ler o texto ao redor do cursor, confirmar o texto para a caixa de texto e enviar eventos de chave brutos para o aplicativo. Os aplicativos precisam estender essa classe em vez de implementar a interface baseInputConnection
: KeyboardView
-
Uma extensão de
View
que renderiza um teclado e responde a eventos de entrada do usuário. O layout do teclado é especificado por um instância deKeyboard
, que você pode definir em um arquivo XML.
Projetar a IU do método de entrada
Há dois elementos visuais principais para um IME: a visualização de entrada e o candidatos. Você só precisa implementar os elementos relevantes para método de entrada que você está projetando.
Visualização de entrada
A visualização de entrada é a IU em que o usuário insere texto na forma de cliques em teclas, escrita à mão ou
gestos. Quando o IME é exibido pela primeira vez, o sistema chama o método
onCreateInputView()
o retorno de chamada. Na implementação desse método, crie o layout que você quer exibir no IME
e retornam o layout ao sistema. O snippet a seguir mostra um exemplo de implementação
O método onCreateInputView()
:
Kotlin
override fun onCreateInputView(): View { return layoutInflater.inflate(R.layout.input, null).apply { if (this is MyKeyboardView) { setOnKeyboardActionListener(this@MyInputMethod) keyboard = latinKeyboard } } }
Java
@Override public View onCreateInputView() { MyKeyboardView inputView = (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null); inputView.setOnKeyboardActionListener(this); inputView.setKeyboard(latinKeyboard); return inputView; }
Neste exemplo, MyKeyboardView
é uma instância de uma implementação personalizada de
KeyboardView
que renderiza um Keyboard
.
Visualização candidata
A visualização candidata é a interface em que o IME exibe possíveis correções ou sugestões de palavras.
para o usuário selecionar. No ciclo de vida do IME, o sistema chama
onCreateCandidatesView()
quando estiver pronto para exibir a visualização candidata. Na sua implementação desse método, retorne uma
que mostre sugestões de palavras ou que retorne "null" se você não quiser mostrar nada. Um valor nulo
é o comportamento padrão. Portanto, não será necessário implementá-la se você não fornecer
sugestões.
Considerações sobre o design da IU
Esta seção descreve algumas considerações de design da interface para IMEs.
Processar vários tamanhos de tela
A interface do seu IME precisa ser capaz de dimensionar para diferentes tamanhos de tela e lidar com o modo paisagem. e na orientação retrato. No modo IME (editor de método de entrada, na sigla em inglês) sem tela cheia, deixe espaço suficiente para que o aplicativo Mostrar o campo de texto e qualquer contexto associado, de modo que não mais da metade da tela seja ocupada por o IME. No modo IME de tela cheia, isso não é um problema.
Processar diferentes tipos de entrada
Os campos de texto do Android permitem definir um tipo de entrada específico, como texto de formato livre, números, URLs endereços de e-mail e strings de pesquisa. Ao implementar um novo IME, detecte o tipo de entrada de cada e forneça a interface apropriada para ele. No entanto, você não precisa configurar o IME para verifica se o usuário digita um texto válido para o tipo de entrada. Isso é responsabilidade que tem o campo de texto.
Por exemplo, esta é a interface que o IME Latin oferece para o texto da plataforma Android entrada:
E esta é a interface que o IME Latin oferece para a plataforma Android entrada numérica:
Quando um campo de entrada recebe foco e o IME é iniciado, o sistema chama
onStartInputView()
,
passando um
Objeto EditorInfo
que contém detalhes sobre o tipo de entrada e outros atributos do campo de texto. Nesse objeto,
as
inputType
contém o tipo de entrada do campo de texto.
O campo inputType
é um int
que contém padrões de bits para vários
configurações de tipo de entrada. Para testar o tipo de entrada do campo de texto, mascare-o com a constante
TYPE_MASK_CLASS
,
assim:
Kotlin
inputType and InputType.TYPE_MASK_CLASS
Java
inputType & InputType.TYPE_MASK_CLASS
O padrão de bits do tipo de entrada pode ter um de vários valores, incluindo:
TYPE_CLASS_NUMBER
- Um campo de texto para inserir números. Conforme ilustrado na figura 3, o IME Latin exibe uma teclado numérico para campos desse tipo.
TYPE_CLASS_DATETIME
- Um campo de texto para inserir data e hora.
TYPE_CLASS_PHONE
- Um campo de texto para inserir números de telefone.
TYPE_CLASS_TEXT
- Um campo de texto para inserir qualquer caractere compatível.
Essas constantes são descritas em mais detalhes na documentação de referência para
InputType
:
O campo inputType
pode conter outros bits que indicam uma variante do campo de texto
tipo, como:
TYPE_TEXT_VARIATION_PASSWORD
- Uma variante de
TYPE_CLASS_TEXT
para inserir senhas. O método de entrada mostra dingbats, em vez de texto real. TYPE_TEXT_VARIATION_URI
- Uma variante de
TYPE_CLASS_TEXT
para inserir URLs da Web e outros recursos uniformes Identificadores (URIs). TYPE_TEXT_FLAG_AUTO_COMPLETE
- Uma variante de
TYPE_CLASS_TEXT
para inserir o texto que o aplicativo é preenchida automaticamente a partir de um dicionário, pesquisa ou outro recurso.
Mascare inputType
com a constante apropriada ao testar essas variantes. A
constantes de máscara disponíveis estão listadas na documentação de referência para InputType
.
Enviar texto para o aplicativo
À medida que o usuário insere texto com seu IME, você pode enviar texto para o aplicativo enviando texto
eventos de tecla ou editando o texto ao redor do cursor no campo de texto do aplicativo. Em ambos os casos,
use uma instância de InputConnection
para entregar o texto. Para conseguir essa instância, chame
InputMethodService.getCurrentInputConnection()
:
Editar o texto ao redor do cursor
Ao editar um texto já existente, alguns métodos úteis
BaseInputConnection
são os seguintes:
-
getTextBeforeCursor()
- Retorna um
CharSequence
contendo o número de caracteres solicitados antes da posição atual do cursor. -
getTextAfterCursor()
- Retorna um
CharSequence
contendo o número de caracteres solicitados a seguir a posição atual do cursor. -
deleteSurroundingText()
- Exclui o número especificado de caracteres antes e depois da posição atual do cursor.
-
commitText()
- Confirma um
CharSequence
no campo de texto e define uma nova posição do cursor.
Por exemplo, o snippet a seguir mostra como substituir os quatro caracteres à esquerda do cursor com o texto "Hello!":
Kotlin
currentInputConnection.also { ic: InputConnection -> ic.deleteSurroundingText(4, 0) ic.commitText("Hello", 1) ic.commitText("!", 1) }
Java
InputConnection ic = getCurrentInputConnection(); ic.deleteSurroundingText(4, 0); ic.commitText("Hello", 1); ic.commitText("!", 1);
Oferecer compatibilidade com a escrita de textos antes de confirmar
Se o IME prevê texto ou requer várias etapas para compor um glifo ou uma palavra, você pode mostrar a
no campo de texto até que o usuário confirme a palavra. Depois, você pode substituir a parte
composição com o texto completo. É possível dar um tratamento especial ao texto adicionando um
span a ele quando passá-lo para
setComposingText()
O snippet a seguir demonstra como mostrar o progresso em um campo de texto:
Kotlin
currentInputConnection.also { ic: InputConnection -> ic.setComposingText("Composi", 1) ic.setComposingText("Composin", 1) ic.commitText("Composing ", 1) }
Java
InputConnection ic = getCurrentInputConnection(); ic.setComposingText("Composi", 1); ic.setComposingText("Composin", 1); ic.commitText("Composing ", 1);
Interceptar eventos de chave de hardware
Mesmo que a janela do método de entrada não tenha foco explícito, ela recebe eventos de tecla de hardware. e pode consumi-los ou encaminhá-los ao aplicativo. Por exemplo, talvez você queira use as teclas de direção para navegar na interface e selecionar candidatos durante a composição. Você também pode capturar a tecla "Voltar" para dispensar todas as caixas de diálogo originadas do método de entrada. janela.
Para interceptar teclas do hardware, substitua
onKeyDown()
e
onKeyUp()
.
Chame o método super()
para as chaves que você não quer processar.
Criar um subtipo de IME
Os subtipos permitem que o IME exponha vários modos de entrada e idiomas compatíveis com um IME. Um subtipo pode representam o seguinte:
- Uma localidade, como en_US ou fr_FR
- Um modo de entrada, como voz, teclado ou escrita à mão
- Outros estilos de entrada, formulários ou propriedades específicos do IME, como 10 teclas ou QWERTY. layouts de teclado
O modo pode ser qualquer texto, como "teclado" ou "voz". Um subtipo também pode expor uma combinação um deles.
As informações de subtipo são usadas para uma caixa de diálogo do seletor de IME que está disponível na barra de notificação. e para as configurações do IME. As informações também permitem que a estrutura exiba um subtipo específico de um IME (editor de método de entrada, na sigla em inglês) diretamente. Ao criar um IME, use o recurso de subtipo, porque ele ajuda o usuário a identificar e alternar entre diferentes idiomas e modos do IME.
Defina os subtipos em um dos arquivos de recurso XML do método de entrada usando a propriedade
<subtype>
. O snippet de código a seguir define um IME com dois subtipos: um
subtipo de teclado para a localidade inglês americano e outro subtipo de teclado para o idioma francês.
localidade da França:
<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.softkeyboard.Settings" android:icon="@drawable/ime_icon"> <subtype android:name="@string/display_name_english_keyboard_ime" android:icon="@drawable/subtype_icon_english_keyboard_ime" android:languageTag="en-US" android:imeSubtypeMode="keyboard" android:imeSubtypeExtraValue="somePrivateOption=true" /> <subtype android:name="@string/display_name_french_keyboard_ime" android:icon="@drawable/subtype_icon_french_keyboard_ime" android:languageTag="fr-FR" android:imeSubtypeMode="keyboard" android:imeSubtypeExtraValue="someVariable=30,someInternalOption=false" /> <subtype android:name="@string/display_name_german_keyboard_ime" ... /> </input-method>
Para garantir que os subtipos sejam rotulados corretamente na interface, use "%s" para receber um marcador de subtipo que é igual ao marcador de localidade do subtipo. Isso é demonstrado nos próximos dois snippets de código. A o primeiro snippet mostra parte do arquivo XML do método de entrada:
<subtype android:label="@string/label_subtype_generic" android:imeSubtypeLocale="en_US" android:icon="@drawable/icon_en_us" android:imeSubtypeMode="keyboard" />
O snippet seguinte faz parte do arquivo strings.xml
do IME. O recurso de string
label_subtype_generic
, que é usado pela definição da interface do método de entrada para definir o
do subtipo, é definido da seguinte forma:
<string name="label_subtype_generic">%s</string>
Essa configuração faz com que o nome de exibição do subtipo corresponda à configuração de localidade. Por exemplo, em qualquer Localidade em inglês, o nome de exibição é "English (United States)".
Escolher os subtipos de IME na barra de notificações
O sistema Android gerencia todos os subtipos expostos por todos os IMEs. Os subtipos de IME são tratados como modos de o IME ao qual pertencem. O usuário pode navegar da barra de notificações ou do aplicativo Configurações para um de subtipos de IME disponíveis, conforme mostrado na figura a seguir:
Escolher os subtipos de IME nas configurações do sistema
O usuário também pode controlar como os subtipos são usados na seção Idioma e painel de configurações de entrada nas configurações do sistema:
Alternar entre os subtipos de IME
Você pode permitir que os usuários alternem facilmente entre os subtipos de IME fornecendo um botão de alternância, como o ícone de idioma em forma de globo no teclado. Isso melhora a usabilidade do teclado e é conveniente para o usuário. Para ativar essa alternância, siga estas etapas:
- Declare
supportsSwitchingToNextInputMethod = "true"
nos arquivos de recursos XML do método de entrada. A declaração precisa ser semelhante a este snippet de código:<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.softkeyboard.Settings" android:icon="@drawable/ime_icon" android:supportsSwitchingToNextInputMethod="true">
- Chame o método
shouldOfferSwitchingToNextInputMethod()
. - Se o método retornar "verdadeiro", exiba um botão de alternância.
- Quando o usuário tocar no botão de alternância, chame
switchToNextInputMethod()
, passando "false". Um valor "false" diz ao sistema para tratar todos os subtipos igualmente, independentemente a qual IME eles pertencem. Especificar "true" exige que o sistema percorra subtipos no o IME atual.
Considerações gerais sobre IME
Veja outros fatores a serem considerados ao implementar o IME:
- Ofereça uma forma para que os usuários ativem opções diretamente da IU do IME.
- Ofereça aos usuários uma maneira de alternar para um IME diferente diretamente da interface do método de entrada, porque vários IMEs podem estar instalados no dispositivo.
- Chame a IU do IME rapidamente. Carregue previamente ou sob demanda os recursos grandes para que os usuários ver o IME assim que tocarem em um campo de texto. Armazene em cache recursos e visualizações para invocações subsequentes do método de entrada.
- Liberar grandes alocações de memória imediatamente após a janela do método de entrada ficar oculta para que que os aplicativos tenham memória suficiente para serem executados. Usar uma mensagem atrasada para liberar recursos se o IME ficar oculto por alguns segundos.
- Garantir que os usuários insiram o máximo de caracteres possível para o idioma ou a localidade associados ao IME. Os usuários podem usar pontuação em senhas ou nomes de usuário. Por isso, seu IME deve fornecer muitos caracteres diferentes para permitir que os usuários insiram uma senha e acessem a dispositivo.