Les éditeurs de texte personnalisés sont des vues qui ne sont pas des composants EditText
ni des widgets de texte WebView
, mais qui acceptent la saisie de texte en implémentant le rappel onCreateInputConnection()
, qui est appelé lorsqu'une vue est sélectionnée et que le système demande un InputConnection
pour cette vue.
Un appel à onCheckIsTextEditor()
à partir d'un éditeur de texte personnalisé doit renvoyer true
.
Prendre en charge l'écriture manuscrite au stylet dans les éditeurs de texte personnalisés
Android 14 (niveau d'API 34) ou version ultérieure est compatible par défaut avec la saisie au stylet dans les composants de saisie de texte Android standards (voir Saisie au stylet dans les champs de texte). Toutefois, les champs de saisie de texte personnalisés (ou éditeurs) nécessitent des efforts supplémentaires de développement.
Pour créer un éditeur de texte personnalisé, procédez comme suit:
- Activer l'initiation de l'écriture manuscrite
- Déclarer la prise en charge de l'écriture manuscrite
- Prendre en charge les gestes d'écriture manuscrite (sélectionner, supprimer, insérer, etc.)
- Fournir l'emplacement du curseur et d'autres données de position à l'IME
- Afficher l'icône de pointage de l'écriture manuscrite au stylet
Activer l'initiation de l'écriture manuscrite
Si une vue ne comporte qu'un seul éditeur de texte, le système de vues peut automatiquement lancer l'écriture manuscrite au stylet pour cette vue. Sinon, la vue doit implémenter sa propre logique d'initiation de l'écriture manuscrite.
Lancement automatique de l'écriture manuscrite
Si une vue affiche un seul éditeur de texte et aucun autre contenu, elle peut activer le lancement automatique de l'écriture manuscrite du système de vues en appelant setAutoHandwritingEnabled(true)
.
Lorsque l'écriture manuscrite est activée, le mouvement du stylet qui commence n'importe où dans les limites de l'écriture manuscrite de la vue lance automatiquement ce mode. L'éditeur du mode de saisie (IME) reçoit les événements de mouvement du stylet et valide le texte reconnu.
![Champ de saisie avec un rectangle autour indiquant les limites de détection des événements de mouvement du stylet.](https://developer.android.com/static/images/develop/ui/compose/touch-input/stylus-input/shared/edittext_handwriting_bounds.png?authuser=5&hl=fr)
EditText
.
Lancement personnalisé de l'écriture manuscrite
Si un affichage contient plusieurs éditeurs de texte ou du contenu en plus d'un seul éditeur de texte, il doit implémenter sa propre logique d'initiation d'écriture manuscrite comme suit:
Désactivez l'initiation automatique de l'écriture manuscrite du système de vues en appelant
setAutoHandwritingEnabled(false)
.Effectuez le suivi de tous les éditeurs de texte visibles dans la vue.
Surveillez les événements de mouvement reçus par la vue dans
dispatchTouchEvent()
.Lorsque le stylet se déplace dans les limites de l'écriture manuscrite d'un éditeur de texte, sélectionnez l'éditeur de texte (s'il n'est pas déjà sélectionné).
Si l'éditeur n'était pas déjà sélectionné, redémarrez l'IME de l'éditeur avec le nouveau contenu en appelant
InputMethodManager#restartInput()
.Démarrez la session d'écriture manuscrite du stylet en appelant
InputMethodManager#startStylusHandwriting()
.
Si un éditeur de texte se trouve dans une vue déroulante, le mouvement du stylet dans les limites de l'écriture manuscrite de l'éditeur doit être considéré comme de l'écriture manuscrite, et non comme un défilement. Utilisez ViewParent#requestDisallowInterceptTouchEvent()
pour empêcher une vue ascendante déroulante d'intercepter les événements tactiles d'un éditeur de texte.
Détails de l'API
MotionEvent#getToolType()
: indique si leMotionEvent
provient d'un stylet, auquel cas la valeur renvoyée estTOOL_TYPE_STYLUS
ouTOOL_TYPE_ERASER
.InputMethodManager#isStylusHandwritingAvailable()
: indique si l'IME est compatible avec l'écriture manuscrite au stylet. Appelez cette méthode avant chaque appel àInputMethodManager#startStylusHandwriting()
, car la disponibilité de l'écriture manuscrite peut avoir changé.InputMethodManager#startStylusHandwriting()
: active le mode d'écriture manuscrite de l'IME. Un événement de mouvementACTION_CANCEL
est envoyé à l'application pour annuler le geste en cours. Les événements de mouvement du stylet ne sont plus envoyés à l'application.Les événements de mouvement du stylet associés au geste actuel qui ont déjà été envoyés à l'application sont transmis à l'IME. L'IME est nécessaire pour afficher une fenêtre d'encre de stylet à travers laquelle il reçoit tous les objets
MotionEvent
suivants. L'IME valide le texte d'écriture manuscrite reconnu à l'aide des APIInputConnection
.Si l'IME ne peut pas passer en mode écriture manuscrite, cet appel de méthode est no-op.
Déclarer la prise en charge de l'écriture manuscrite
Lorsque vous remplissez l'argument EditorInfo
de View#onCreateInputConnection(EditorInfo)
, appelez setStylusHandwritingEnabled()
pour informer l'IME que l'éditeur de texte prend en charge l'écriture manuscrite.
Déclarez les gestes compatibles avec setSupportedHandwritingGestures()
et setSupportedHandwritingGesturePreviews()
.
Prendre en charge les gestes d'écriture manuscrite
Les IME peuvent accepter divers gestes d'écriture manuscrite, par exemple entourer le texte pour le sélectionner ou en griffonnant sur du texte pour le supprimer.
Les éditeurs personnalisés implémentent InputConnection#performHandwritingGesture()
et InputConnection#previewHandwritingGesture()
pour prendre en charge différents types de HandwritingGesture
, tels que SelectGesture
, DeleteGesture
et InsertGesture
.
Déclarez les gestes d'écriture manuscrite acceptés lors de la saisie de l'argument EditorInfo
de View#onCreateInputConnection(EditorInfo)
(consultez la section Déclarer la prise en charge de l'écriture manuscrite).
Détails de l'API
InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer)
: implémente des gestes. L'argumentHandwritingGesture
contient des informations de localisation que vous pouvez utiliser pour déterminer où effectuer le geste dans le texte. Par exemple,SelectGesture
fournit un objetRectF
qui spécifie la plage de texte sélectionnée, etInsertGesture
fournit un objetPointF
qui spécifie le décalage du texte auquel insérer le texte.Utilisez les paramètres
Executor
etIntConsumer
pour renvoyer le résultat de l'opération. Lorsque les arguments de l'exécuteur et des clients sont fournis, utilisez l'exécuteur pour appelerIntConsumer#accept()
, par exemple:executor.execute { consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS) }
HandwritingGesture#getFallbackText()
: fournit le texte de remplacement validé par l'IME à la position du curseur si aucun texte applicable ne se trouve sous la zone d'un geste d'écriture manuscrite.Parfois, l'IME n'est pas en mesure de déterminer si un geste au stylet est destiné à effectuer une opération gestuelle ou à écrire à la main. Un éditeur de texte personnalisé est chargé de déterminer l'intention de l'utilisateur et d'effectuer l'action appropriée (en fonction du contexte) à l'emplacement du geste.
Par exemple, si l'IME ne peut pas déterminer si l'utilisateur voulait dessiner un caret vers le bas ⋁ pour effectuer un geste d'insertion d'espace ou pour écrire la lettre "v" à la main, il peut envoyer un
InsertGesture
avec le texte de remplacement "v".L'éditeur doit d'abord essayer d'effectuer le geste d'insertion d'espace. Si le geste ne peut pas être effectué (par exemple, s'il n'y a pas de texte à l'emplacement spécifié), l'éditeur doit insérer la lettre "v" à la position du curseur.
InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal)
: prévisualise un geste en cours. Par exemple, lorsque l'utilisateur commence à dessiner un cercle autour du texte, un aperçu en direct de la sélection obtenue peut être affiché et mis à jour en continu à mesure que l'utilisateur continue de dessiner. Seuls certains types de gestes peuvent être prévisualisés (voirPreviewableHandwritingGesture
).Le paramètre
CancellationSignal
peut être utilisé par l'IME pour annuler l'aperçu. Si d'autres événements perturbent l'aperçu (par exemple, si du texte est modifié de façon programmatique ou que de nouvelles commandesInputConnection
se produisent), l'éditeur personnalisé peut annuler l'aperçu.Les gestes d'aperçu ne sont destinés qu'à l'affichage et ne doivent pas modifier l'état de l'éditeur. Par exemple, un aperçu
SelectGesture
masque la plage de sélection actuelle de l'éditeur et met en surbrillance la plage d'aperçu des gestes. Toutefois, une fois l'aperçu annulé, l'éditeur doit restaurer sa plage de sélection précédente.
Fournir l'emplacement du curseur et d'autres données de position
En mode écriture manuscrite, l'IME peut demander l'emplacement du curseur et d'autres données de position à l'aide de InputConnection#requestCursorUpdates()
.
L'éditeur personnalisé répond par un appel à InputMethodManager#updateCursorAnchorInfo(View,
CursorAnchorInfo)
.
Les données de CursorAnchorInfo
concernant l'écriture manuscrite au stylet sont fournies via les méthodes CursorAnchorInfo.Builder
suivantes:
setInsertionMarkerLocation()
: définit la position du curseur. L'IME utilise cette valeur pour animer l'encre d'écriture manuscrite à l'emplacement du curseur.setEditorBoundsInfo()
: définit les limites de l'éditeur et de l'écriture manuscrite. L'IME utilise ces données pour positionner la barre d'outils d'écriture manuscrite de l'IME à l'écran.addVisibleLineBounds()
: définit les limites de toutes les lignes de texte visibles (ou partiellement visibles) dans l'éditeur. L'IME utilise les limites des lignes pour améliorer la précision de la reconnaissance des gestes d'écriture manuscrite.setTextAppearanceInfo()
: définit l'apparence du texte à l'aide des informations issues du champ de saisie de texte. L'IME utilise ces informations pour styliser l'encre d'écriture manuscrite.
Afficher l'icône de pointage de l'écriture manuscrite au stylet
Affichez l'icône de pointage de l'écriture manuscrite au stylet lorsque le stylet pointe sur les limites d'écriture manuscrite de votre éditeur de texte personnalisé et que l'IME sélectionné est compatible avec l'écriture manuscrite au stylet (InputMethodManager#isStylusHandwritingAvailable()
).
Ignorez View#onResolvePointerIcon()
pour obtenir une icône de pointage pour l'écriture manuscrite au stylet. Dans le forçage, appelez PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING)
pour accéder à l'icône de pointage de l'écriture manuscrite du stylet du système.