10
votes

Android: Comment déterminer l'index des caractères d'un événement tactile dans TextView?

J'ai un textview avec un ouchlistener . Ce que je veux, c'est l'index du personnage que l'utilisateur pointe lorsque je reçois le motionEvent . Y a-t-il un moyen d'accéder aux métriques de polices sous-jacentes du textview ?


0 commentaires

3 Réponses :


5
votes

Je ne suis pas au courant d'une simple façon directe de le faire, mais vous devriez être capable de mettre quelque chose ensemble à l'aide de peinture objet du TextView via un appel à textview.getpaint ()

Une fois que vous avez l'objet de peinture, vous aurez accès aux caractères de police sous-jacents via un appel à peinture.getfontmetrics () et avoir accès à d'autres fonctions telles que peinture.MeasureText () peinture.getTextbounds () et peinture.getTextbounds () pour accéder à la taille réelle du texte affiché.


2 commentaires

Merci, j'ai fini par utiliser ceci. Dommage, il n'y a pas de type «pointtocharacterindex» simple, mais il ne s'agissait pas de la science de la roquette pour rouler le mien grâce à la peinture.


@Tony Blues Répondre a le genre de chose pointutocharacterindex que vous recherchez.



25
votes

Avez-vous essayé quelque chose comme ceci: xxx

espère que cela aide ...


5 commentaires

J'ai demandé aux googles ingénieurs sur Google Io Office Horly, et c'est la même chose qu'ils ont proposé.


Je suis si heureux que j'ai trouvé cette réponse, merci Tony! Ça marche parfaitement bien! Maintenant, je n'ai aucun problème avec les événements tactiles, même si le TextView contient des images. :-)


Merci d'avoir sauvé ma vie :)


Stackoverflow.com/Questtions/62528990/...


Au cas où quelqu'un veut la position de caractère lorsque vous connaîtrez l'index de caractère Stackoverflow.com/a/56740416/2736039



4
votes

Bien que cela fonctionne généralement, j'ai eu quelques problèmes avec la réponse de Tony Blues.

Premièrement geoffsetforhorizontal renvoie un décalage même si la coordonnée X est bien au-delà du dernier caractère de la ligne.

Deuxièmement, le décalage de caractère retourné appartient parfois au décalage de caractère renvoyé. au caractère suivant, pas le personnage directement sous le pointeur. Apparemment, la méthode renvoie le décalage de la position du curseur le plus proche. Cela peut être à gauche ou à la droite du personnage en fonction de ce qui est plus proche.

Ma solution utilise GETPRIMARYHORIZONTAL Pour déterminer la position du curseur d'un certain décalage et utilise une recherche binaire pour trouver le décalage sous la coordonnée X du pointeur. < Pré> XXX

EDIT: Cette version mise à jour fonctionne mieux avec des pauses de ligne non naturelles, lorsqu'un mot long ne correspond pas à une ligne et se divise quelque part au milieu.

CAVEATS: Textes hyphénagés, en cliquant sur le trait d'union à la fin d'une ligne renvoyer l'index du personnage à côté de celui-ci. De plus, cette méthode ne fonctionne pas bien avec les textes RTL.


11 commentaires

Merci pour l'info. Mais ma question est que TextView's geoffsetForPorposition () n'a pas fonctionné pour vous? Il utilise également GetLleLowForSvertical () et GeoffSetForhorizontal () sous la hotte, mais cela fait un calcul supplémentaire pour être plus précis. J'ai voté quand même :)


@Jenix, je viens de courir un test rapide et il semble que Textview.getoffsetforPosition renvoie également souvent le décalage du caractère suivant à droite au lieu du caractère directement sous le pointeur. Essayez d'augmenter la taille de la police de la vue textuelle à quelque chose de assez grand à voir par vous-même.


Hey, c'est moi encore moi! :) Pendant que j'aime le plus, cela a un problème sérieux (au moins pour moi). Chaque fois que la pause de ligne automatique fonctionne sur le texte, ce code ne parvient pas à ramasser chaque dernier caractère de chaque ligne, à l'exception du très dernier. Si je mettais manuellement des caractères de pause de ligne aux mêmes positions dans le texte, cela fonctionne très bien. Savez-vous pourquoi cela se produit?


@Jenix j'ai déjà testé cela dans un émulateur Android 9 et je ne pouvais pas reproduire le problème.



J'ai créé une nouvelle Android ProEjct vide et mettez une vue textuelle qui est la même que ci-dessus. Utilisation de votre code, je reçois -1 lorsque je touche les caractères F, M, S, Y, qui sont les derniers dans chaque ligne. J'ai fait de nombreux tests comme celui-ci et j'ai fait de nouveau après avoir lu votre nouveau commentaire mais le même. Confirmé sur Samsung Galaxy Note 2, S7 Edge, et même sur les émulateurs de Genymotion ..


Ah je n'ai pas testé sur Android 9 mais il ne sert à rien de savoir si les autres ne fonctionnent pas comme prévu.


@Jenix Désolé, je ne faisais que tester avec des pauses naturelles (espaces dans le texte d'entrée), je suppose que cela n'a rien à voir avec la version Android.


@Jenix Avant de mettre à jour ma réponse, veuillez tester cette version: GIST.GITUB.COM/DevConsole/64040ec74BDE98F59F2D70AA6BFAF4E1<


Super! Excellent! Fonctionne comme un charme! Merci beaucoup!


Juste curieux. Pensez-vous que votre code est plus cher que TEXTVIEW.GETOFFSSETFORPOSITION ?