Mise à l'Échelle Auto TextView Texte à l'intérieur de Limites
Je suis à la recherche d'une façon optimale pour redimensionner l'habillage du texte dans un TextView
pour qu'elle s'adapte à l'intérieur de ses getHeight et getWidth limites. Je ne suis pas simplement à la recherche d'un moyen pour faire passer le texte - je veux m'assurer à la fois des enveloppements et est assez petit pour tenir entièrement sur l'écran.
J'ai vu quelques cas sur StackOverflow où d'auto redimensionnement qui était nécessaire, mais ils sont soit des cas très particuliers avec hack solutions, n'ont pas de solution, ou qui impliquent de re-dessiner le TextView
de manière récursive jusqu'à ce qu'il soit assez petit (ce qui est de la mémoire intenses et des forces à l'utilisateur de regarder le texte de rétrécissement, étape par étape, à chaque récursion).
Mais je suis sûr que quelqu'un a trouvé une bonne solution qui n'implique pas ce que je fais: l'écriture de plusieurs lourde des routines d'analyser et de mesurer le texte, de redimensionner le texte, et répéter jusqu'à ce qu'un appareil de petite taille, il a été trouvé.
Ce que les routines ne TextView
utiliser pour envelopper le texte? Ne pouvait pas ceux qui sont en quelque sorte utilisé pour prédire si le texte sera suffisamment petit?
tl;dr: est-il une bonne pratique de l'auto-redimensionner une TextView
pour s'adapter, enveloppé, dans son getHeight et getWidth limites?
- J'ai aussi essayé d'utiliser le getEllipsisCount dans StaticLayout à détecter le moment où le texte a été de sortir des limites du terrain, mais qui ne fonctionnait pas pour moi, j'avais demandé à parler: stackoverflow.com/questions/5084647/...
- Pourquoi ne t vous dessinez un patch neuf textview ? il sera automatiquement ajuster à ses limites. Suis-je de vous obtenir de droite frère?
- Patch neuf textview? Je ne suis pas familier avec neuf-patch, il semble être un format d'image chose, mais... je suis à la recherche de la documentation sur la façon dont cela pourrait être utilisé avec un textview. Savoir où je pourrais obtenir plus d'informations?
- À la lecture sur un peu plus loin, je reçois l'impression que neuf-patch est juste pour le redimensionnement de quelque chose qui a déjà un format défini - mais j'ai besoin de quelque chose qui va prendre une corde et de trouver sa taille optimale et le format à l'intérieur de certaines limites.
- Double Possible de: stackoverflow.com/a/7875656/435605
- J'ai trouvé une bibliothèque qui semble faire cela automatiquement: ankri.de/autoscale-textview ne l'ai pas testé si
- J'ai eu un bref coup d'œil à la bibliothèque mentionné par Seppl - il manque de la fonction de ellipsising le texte si c'est trop long, même à la plus petite textsize, qui Chase solution offre. Donc, si le texte est trop long, le textview, la hauteur augmente, ce qui n'est pas la question posée.
Vous devez vous connecter pour publier un commentaire.
De juin 2018 Android officiellement commencé à l'appui de cette fonction pour Android 4.0 (API de niveau 14) et de la hausse.
Consultez-le à l': Redimensionnement Automatique TextViews
Avec Android 8.0 API (niveau 26) et plus:
Programme:
Les versions d'Android antérieures à Android 8.0 API (niveau 26):
Programme:
À l'Attention de: TextView doit avoir layout_width="match_parent" ou taille absolue!
implementation 'com.android.support:support-compat:28.0.0'
dansapp/build.gradle
pour laapp: ...
attributs de travailler.Mise à JOUR: code Suivant répond également à l'exigence d'un idéal AutoScaleTextView comme décrit ici : Ajustement automatique de la TextView pour Android et est marqué comme gagnant.
Mise à JOUR 2: Soutien de maxlines ajouté, maintenant fonctionne bien avant de l'API de niveau 16.
Mise à jour 3: Soutien pour
android:drawableLeft
,android:drawableRight
,android:drawableTop
etandroid:drawableBottom
balises ajoutées, grâce à MartinH est simple correctif ici.Mes besoins étaient un peu différentes. J'ai besoin d'un moyen efficace de régler la taille parce que j'étais l'animation d'un nombre entier à partir, peut être de 0 à ~4000 dans
TextView
en 2 secondes et j'ai voulu régler la taille en conséquence. Ma solution fonctionne à peu différemment. Voici ce résultat final ressemble:et le code qui l'a produite:
Et enfin le code java:
getMaxLines ()
méthode, il a été ajouté dans l'API de niveau 16. Nous avons donné notre propre mise en œuvre degetMaxLines
afin qu'il fonctionne. La Documentation de @TargetApi dit Indique que la Charpie doit traiter ce type de ciblage d'une API de niveau, peu importe ce que l'objectif du projet est. stackoverflow.com/questions/14341042/...getText()
contiendra toujoursString
objet afin de l'ensemble du code a été intégré avec(String)getText()
ce qui était faux. J'ai mis à jour le code et remplace tous ces événements avecgetText().toString()
. Nous espérons qu'il permettra de résoudre votre problème.StaticLayout
ne respecte paswidth
. Juste de remplacer le dernier retour de lignes deonTestSize()
avec ce " si (availableSpace.contient(mTextRect)) { // peut-être trop petit, ne vous inquiétez pas, nous allons trouver la meilleure correspondance return -1; } else { if (mTextRect.bas < availableSpace.bas && mTextRect.droit > availableSpace.droite) { // hack :O return -1; } // trop grand return 1; }'EditText
et puis essayez android:layout_height="100dp" android:maxLines="1" et d'écrire quelque chose. Je suppose que cela devrait fonctionner.AutoResizeTextView
de réajuster sa taille, et j'ai remarqué que la taille seront plus grands. Comme je ne cesse de déconner avec le edittext, leAutoResizeTextView
ajuste de plus en plus grande jusqu'à ce qu'il atteigne le point où il s'intègre parfaitement. Aucune idée de pourquoi l'image ne fonctionne pas correctement et j'ai besoin de déclencher le onSizeChanged() la méthode à plusieurs reprises jusqu'à ce que je obtenir la bonne taille?En fait une solution de Google DialogTitle classe... si ce n'est pas aussi efficace que la reconnus, c'est beaucoup plus simple et il est facile de s'adapter.
requestLayout
dansonTextChanged
. Même avec cette correction, la solution n'est pas applicable dans de nombreux cas, comme la réduction de la textSize par 1 ne semble pas fonctionne dans tous les cas: nous pouvons avoir besoin de réduire la textSize plus loin.super.onMeasure(widthMeasureSpec, heightMeasureSpec);
ne cause pas une récursivité, maismeasure(widthMeasureSpec, heightMeasureSpec);
. J'ai donc changé pour " mesurer(widthMeasureSpec, heightMeasureSpec);" et il fonctionne. Je viens de tester sur Android 4.4(Nexus 5) et Android 4.0.4(Samsung SII-LTE) et il a bien fonctionné avec deux d'entre eux (j'ai même utilisé la coutume de la FTO police Japonaise). Prends mon fix ici: gist.github.com/mrleolink/0dfeef749da1b854a44bmaxLines
etrequestLayout()
sursetText
comme @adbie dit. FixedLineTextView -> gist.github.com/Kevinrob/09742d9069e4e4e4ab66width=0dp
etlayout_weight
est réglé. Dans mon cas, TextView est à l'intérieur GridView et le texte est codé en utf-8.J'ai commencé avec Chase solution, mais a dû s'adapter à deux choses avant qu'il travaillait comme prévu sur mon téléphone (Galaxy Nexus, Android 4.1):
à l'aide d'une copie de TextPaint pour la mesure de mise en page
La documentation pour TextView.getPaint() déclare qu'il devrait être utilisé en lecture seule, donc j'ai fait une copie dans les deux endroits où l'on utilise la peinture à l'objet de mesure:
l'ajout d'une unité de réglage de la taille du texte
Avec ces deux modifications, la solution fonctionne parfaitement pour moi, merci Chase! Je ne sais pas si c'est dû à Android 4.x que la solution d'origine ne fonctionnait pas. Dans le cas où vous voulez le voir en action ou de tester si ça marche vraiment sur votre appareil, vous pouvez jeter un oeil à mon flashcard application Flashcards ToGo où j'utilise cette solution à l'échelle le texte d'une carte mémoire. Le texte peut avoir une longueur arbitraire, et les cartes mémoire sont affichés dans les différentes activités, parfois petits, parfois, de plus grand, de plus dans le paysage + portrait mode, et je n'ai pas trouvé le coin de cas où la solution serait de ne pas fonctionner correctement...
Une solution de contournement pour Android 4.x:
J'ai trouvé AutoResizeTextView et il fonctionne très bien sur mon Android 2.1 émulateur. Je l'aime beaucoup. Mais malheureusement, il a échoué sur mon propre 4.0.4 téléphone portable et 4.1 de l'émulateur. Après avoir essayé, j'ai trouvé qu'il pourrait être facilement résolu par l'ajout d'attributs suivants dans AutoResizeTextView classe dans le fichier xml:
Avec les 2 lignes ci-dessus, maintenant AutoResizeTextView fonctionne parfaitement sur mon 2.1 & 4.1 émulateurs et mon propre 4.0.4 téléphone portable maintenant.
Espère que cela vous aide. 🙂
Avertissement, bug sur Android Honeycomb et Ice Cream Sandwich
Androïdes versions: 3.1 - 4.04 avoir un bug, que setTextSize() à l'intérieur de TextView ne fonctionne que pour la 1ère fois (1er invocation).
Bug est décrit ici: http://code.google.com/p/android/issues/detail?id=22493 http://code.google.com/p/android/issues/detail?id=17343#c9
solution de contournement consiste à ajouter un caractère de nouvelle ligne de texte attribué à TextView avant de changer de taille:
Je l'utilise dans mon code comme suit:
- Je ajouter cette "\u3000" le caractère à gauche et à droite de mon texte, de sorte qu'il reste centré. Si vous avez aligné à gauche, puis ajouter à la droite. Bien sûr, il peut être également intégré avec AutoResizeTextView widget, mais je voulais garder corriger le code de l'extérieur.
AppcompatTextView prend désormais en charge le dimensionnement automatique à partir de l'Appui de la Bibliothèque de 26,0. TextView Android O fonctionne également de la même manière. Plus d'informations peuvent être trouvées ici. Une simple démo app ici.
android:lines="1"
dans le TextView pour redimensionner le texte. Sans cet attribut, le texte a été enveloppé dans des deux lignes.Mon besoin était de redimensionner le texte afin de s'adapter parfaitement à la vue de limites. Chase solution seulement de réduire la taille du texte, celui-ci élargit également le texte s'il y a assez d'espace.
À faire tous les rapide & précis j'ai utilisé une méthode de bissection au lieu d'un processus itératif, alors que, comme vous pouvez le voir dans
resizeText()
méthode. C'est pourquoi vous avez également unMAX_TEXT_SIZE
option. J'ai aussi inclus onoelle conseils.Testé sur Android 4.4
Au google IO conférence en 2017, google a introduit la propriété autoSize de TextView
https://youtu.be/fjUdJ2aVqE4
Depuis que j'ai été la recherche de ce pour toujours, et j'ai trouvé une solution il y a un moment qui manque ici, je vais l'écrire ici, pour la future référence.
Remarque: ce code a été prise directement à partir de Google, Android Lollipop dialer a quelques temps, je ne me souviens pas Si des modifications ont été apportées à l'époque. Aussi, je ne sais pas quelle licence est cette vertu, mais j'ai des raisons de penser qu'il est
Apache 2.0
.Classe
ResizeTextView
, leView
Ce
ResizeTextView
classe pourrait s'étendre TextView et tous ses enfants comme je le comprenons, donc EditText ainsi.Classe
ViewUtil
avec la méthoderesizeText(...)
Vous devez définir votre point de vue en tant que
Espère que cela aide!
J'espère que cela vous aide à
REMARQUE: j'utilise MAX_TEXT_SIZE dans le cas de la taille du texte est plus grand que 20 parce que je ne veux pas permettre de grandes polices s'applique à mon avis, si ce n'est pas votre cas, vous pouvez simplement le supprimer.
scale > availableWidth
? Cela permettra de redimensionner UNIQUEMENT si la taille est plus petite qu'elle ne l'était à l'origine; d'étirement (ou mettre le texte en plus gros) ne se produira pas.J'ai écrit un billet de blog à ce sujet.
J'ai créé un composant appelé
ResizableButton
basé sur Kirill Grouchnikov de post de blog sur les composants utilisés dans la nouvelle application android market. J'ai placé le code src ici.D'autre part, mosabua lire mon post et m'a dit qu'il allait ouvrir la source de sa mise en œuvre qui a été plus rapide que le mien. J'espère qu'il le libérer assez tôt 🙂
Voici une solution simple qui utilise TextView lui-même avec un TextChangedListened ajouté:
Cette approche permettra d'augmenter ou de diminuer la taille de la police comme nécessaire pour adapter le texte, en respectant le MIN_SP et MAX_SP limites reçus en tant que paramètres.
Mon application est un peu plus complexe, mais est livré avec les éléments suivants goodies:
[révisé le 2012-11-21]
J'ai trouvé le suivant fonctionne bien pour moi. Il ne tourne pas en boucle, et représente à la fois la hauteur et la largeur. Notez qu'il est important de spécifier l'unité PX lors de l'appel de setTextSize sur la vue.
Voici la routine que j'utilise, en passant dans le getPaint() de la vue. 10 chaîne de caractère avec un grand caractère est utilisé pour estimer la largeur indépendant de la chaîne réelle.
Voici une énumération de ce que j'ai trouvé pour ceux qui sont encore à la recherche:
1) Voici une solution que de manière récursive re-peint le textview jusqu'à ce qu'il s'adapte. Cela signifie littéralement regarder votre texte rétrécir en place, mais au moins il tient quand c'est fait. Le code a besoin de quelques ajustements à mettre en œuvre, mais il est surtout là.
2) Vous pouvez essayer de piratage ensemble une solution personnalisée comme cette, ou dunni classe dans cette, qui est ce que j'ai fait à l'aide de la getPaint().savoir measuretext(str) à la recherche de la bonne taille, mais il a eu beaucoup de messier car j'ai besoin d'elle pour l'envelopper seulement sur les espaces...
3) Vous pouvez continuer à chercher - j'ai essayé plus de solutions de rechange que je peux compter. Ted conseils sur StaticLayout n'a pas payé pour moi, mais peut-être il ya quelque chose là-bas; j'ai essayé d'utiliser le StaticLayout.getEllipsis(ligne) afin de déterminer si le texte a été d'aller hors de l'écran, pas d'effet. Voir mon (actuellement de l'onu-ont répondu) post à ce sujet ici.
J'avais besoin d'une solution spécifique. J'ai un edittext et textview dans ma mise en page. Le textview est fixé de hauteur et de largeur. Lorsque l'utilisateur commence à taper dans l'edittext, le texte doit apparaître immédiatement dans le textview. Le texte dans le champ de l'auto - redimensionner pour s'adapter à la textview. J'ai donc mis à jour Chase solution à travailler pour moi. Ainsi, lorsque la modification du texte dans le textview, redimensionnement commence. La différence entre le mien et Chase soluton: le redimensionnement est fait, même si l'utilisateur de SUPPRIMER certains caractères. J'espère que cela peut aider quelqu'un.
Vous pouvez utiliser le
android.text.StaticLayout
classe pour cette. C'est ce queTextView
utilise en interne.Je viens de créer la méthode suivante (sur la base des idées de Chasse) qui pourrait vous aider si vous voulez dessiner du texte à toute la toile:
Cela pourrait par exemple être utilisée dans tous les onDraw() la méthode de vue personnalisée.
Voici encore une autre solution, juste pour le plaisir. Ce n'est probablement pas très efficace, mais il ne veut faire face à la fois la hauteur et la largeur du texte, et avec le texte annoté.
Je combiner certaines des suggestions ci-dessus pour faire une que les échelles en haut et en bas, avec la méthode de la bissection. Il s'adapte aussi à l'intérieur de la largeur.
J'ai utiliser le code de la chasse et de M-WaJeEh
et j'ai trouvé un certain avantage & inconvénient ici
de chase
de M-WaJeEh
getTextHeight()
lors de la mise en texte ou la taille du texte. Android 4.0.4 émulateur.java.lang.IllegalArgumentException: Layout: -40 < 0 at android.text.Layout.<init>(Layout.java:140) at android.text.StaticLayout.<init>(StaticLayout.java:104) at android.text.StaticLayout.<init>(StaticLayout.java:90) at android.text.StaticLayout.<init>(StaticLayout.java:68) at android.text.StaticLayout.<init>(StaticLayout.java:48)
Si quelqu'un en a besoin, ici, est le même extrait de code, mais pour Xamarin.Android.
Fournir cette version de réponse sommet réécrit sur C# pour ceux qui codes sur Xamarin.Android. A travaillé pour moi bien.
Ma méthode est la suivante:
Par exemple:
Cette solutions travaille pour nous:
CustomFontButtonTextFit
de laButton
classe puis l'INTERFACE utilisateur ne se montre jamais. Je dirais que cette classe est cassé...Grâce à la chasse et onoelle, pour les programmeurs paresseux, permettez-moi de poster ici une version de travail de leur fantastique fusionné code, adapté sur un Bouton, au lieu d'un TextView.
Substitut à tous vos Boutons (pas ImageButtons) avec AutoResizeTextButtons et même ennuyeuse problème est résolu pour eux aussi.
Voici le code. J'ai juste enlevé les importations.
Utilisation:
mettre un AutoResizeTextButton à l'intérieur de votre xml dans le remplacement d'un Bouton normal, sans changer
quelque chose d'autre.
À l'intérieur de la onCreate() mettre (par exemple):
Ici est l'approche que je prends. C'est très simple. Il utilise successive approximation à zéro dans sur la taille de la police et peut généralement l'ai trouvé en moins de 10 itérations. Il suffit de remplacer "activityWidth" avec la largeur de ce point de vue, vous utilisez pour afficher le texte. Dans mon exemple, il est défini comme un champ privé de la largeur de l'écran. Le premier fontsize de 198 est seulement dans le cas de la méthode génère une exception (qui ne devrait jamais arriver):
Étendre TextView et remplacer onDraw avec le code ci-dessous. Il permettra de conserver le texte de l'aspect ratio, mais la taille de remplir l'espace. Vous pouvez facilement modifier le code pour étirer si nécessaire.
rect
viennent?Reportez-vous à la
ScalableTextView.java
ici Ajustement automatique de la TextView pour Android. J'ai ajouté le code pour réduire et développer le TextView basé sur la longueur du texteJe viens d'emprunter à d'autres types de " l'idée et écrire un peu de code ci-dessous qui peuvent être utiles.