233 votes

TextView à ajustement automatique pour Android

Contexte

Souvent, nous avons besoin d'adapter automatiquement la police du TextView aux limites qui lui sont données.

Le problème

Malheureusement, même s'il existe de nombreux fils de discussion et messages (et des solutions proposées) traitant de ce problème (exemple ici , ici et ici ), aucune d'entre elles ne fonctionne vraiment bien.

C'est pourquoi j'ai décidé de tester chacun d'entre eux jusqu'à ce que je trouve le bon.

Je pense que les exigences d'un tel textView devraient être les suivantes :

  1. Doit permettre l'utilisation de n'importe quelle police, caractère, style et jeu de caractères.

  2. Doit gérer à la fois la largeur et la hauteur

  3. Pas de troncature, sauf si le texte ne peut pas tenir en raison de la limitation que nous lui avons (exemple : texte trop long, taille disponible trop petite). Cependant, nous pouvons demander une barre de défilement horizontale/verticale si nous le souhaitons, juste pour ces cas.

  4. Devrait permettre une utilisation sur plusieurs lignes ou sur une seule ligne. Dans le cas d'un système multi-lignes, il faut autoriser les lignes maximum et minimum.

  5. Ne doit pas être lent à calculer. Vous utilisez une boucle pour trouver la meilleure taille ? Optimisez-la au moins et n'incrémentez pas votre échantillonnage de 1 à chaque fois.

  6. Dans le cas d'un système multi-lignes, il faudrait permettre de préférer le redimensionnement ou l'utilisation de plus de lignes, et/ou permettre de choisir les lignes nous-mêmes en utilisant le " \n ".

Ce que j'ai essayé

J'ai essayé tant d'échantillons (y compris ceux des liens dont j'ai parlé), et j'ai aussi essayé de les modifier pour gérer les cas dont j'ai parlé, mais aucun ne fonctionne vraiment.

J'ai créé un projet d'exemple qui me permet de vérifier visuellement si le TextView s'adapte correctement.

Actuellement, mon projet d'exemple ne fait que randomiser le texte (l'alphabet anglais plus les chiffres) et la taille de la TextView, et le laisse rester sur une seule ligne, mais même cela ne fonctionne pas bien sur tous les échantillons que j'ai essayés.

Voici le code (également disponible ici ) :

Fichier res/layout/activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
  android:layout_height="match_parent" tools:context=".MainActivity">
  <Button android:id="@+id/button1" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true" android:text="Button" />
  <FrameLayout android:layout_width="match_parent"
    android:layout_height="wrap_content" android:layout_above="@+id/button1"
    android:layout_alignParentLeft="true" android:background="#ffff0000"
    android:layout_alignParentRight="true" android:id="@+id/container"
    android:layout_alignParentTop="true" />

</RelativeLayout>

Fichier src/.../MainActivity.java

public class MainActivity extends Activity
  {
  private final Random        _random            =new Random();
  private static final String ALLOWED_CHARACTERS ="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";

  @Override
  protected void onCreate(final Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ViewGroup container=(ViewGroup)findViewById(R.id.container);
    findViewById(R.id.button1).setOnClickListener(new OnClickListener()
      {
        @Override
        public void onClick(final View v)
          {
          container.removeAllViews();
          final int maxWidth=container.getWidth();
          final int maxHeight=container.getHeight();
          final FontFitTextView fontFitTextView=new FontFitTextView(MainActivity.this);
          final int width=_random.nextInt(maxWidth)+1;
          final int height=_random.nextInt(maxHeight)+1;
          fontFitTextView.setLayoutParams(new LayoutParams(width,height));
          fontFitTextView.setSingleLine();
          fontFitTextView.setBackgroundColor(0xff00ff00);
          final String text=getRandomText();
          fontFitTextView.setText(text);
          container.addView(fontFitTextView);
          Log.d("DEBUG","width:"+width+" height:"+height+" text:"+text);
          }
      });
    }

  private String getRandomText()
    {
    final int textLength=_random.nextInt(20)+1;
    final StringBuilder builder=new StringBuilder();
    for(int i=0;i<textLength;++i)
      builder.append(ALLOWED_CHARACTERS.charAt(_random.nextInt(ALLOWED_CHARACTERS.length())));
    return builder.toString();
    }
  }

La question

Quelqu'un connaît-il une solution à ce problème courant qui fonctionne réellement ?

Même une solution qui a beaucoup moins de fonctionnalités que ce que j'ai écrit, par exemple une solution qui a juste un nombre constant de lignes de texte, et ajuste sa police en fonction de sa taille, n'a jamais de problèmes bizarres et le texte devient trop grand/petit par rapport à son espace disponible.


Projet GitHub

Puisqu'il s'agit d'un TextView si important, j'ai décidé de publier une bibliothèque, afin que tout le monde puisse facilement l'utiliser, et y contribuer, ici .

0 votes

Avez-vous essayé celui-ci ? androidviews.net/2012/12/autoscale-textview

0 votes

@Thrakbad c'est l'un des liens que j'ai mentionné. Il ne passe pas non plus le test.

0 votes

Désolé, j'ai raté le dernier exemple.

148voto

M-WaJeEh Points 5957

Grâce à la solution simple de MartinH ici ce code s'occupe également de android:drawableLeft , android:drawableRight , android:drawableTop et android:drawableBottom tags.


Ma réponse ici devrait vous rendre heureux Mise à l'échelle automatique du texte du TextView pour qu'il s'adapte à ses limites

J'ai modifié votre cas de test :

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ViewGroup container = (ViewGroup) findViewById(R.id.container);
    findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(final View v) {
            container.removeAllViews();
            final int maxWidth = container.getWidth();
            final int maxHeight = container.getHeight();
            final AutoResizeTextView fontFitTextView = new AutoResizeTextView(MainActivity.this);
            final int width = _random.nextInt(maxWidth) + 1;
            final int height = _random.nextInt(maxHeight) + 1;
            fontFitTextView.setLayoutParams(new FrameLayout.LayoutParams(
                    width, height));
            int maxLines = _random.nextInt(4) + 1;
            fontFitTextView.setMaxLines(maxLines);
            fontFitTextView.setTextSize(500);// max size
            fontFitTextView.enableSizeCache(false);
            fontFitTextView.setBackgroundColor(0xff00ff00);
            final String text = getRandomText();
            fontFitTextView.setText(text);
            container.addView(fontFitTextView);
            Log.d("DEBUG", "width:" + width + " height:" + height
                    + " text:" + text + " maxLines:" + maxLines);
        }
    });
}

J'affiche le code ici à per Le développeur Android demande :

Effet final :

Enter image description here

Exemple de fichier de mise en page :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp" >

<com.vj.widgets.AutoResizeTextView
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:ellipsize="none"
    android:maxLines="2"
    android:text="Auto Resized Text, max 2 lines"
    android:textSize="100sp" /> <!-- maximum size -->

<com.vj.widgets.AutoResizeTextView
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:ellipsize="none"
    android:gravity="center"
    android:maxLines="1"
    android:text="Auto Resized Text, max 1 line"
    android:textSize="100sp" /> <!-- maximum size -->

<com.vj.widgets.AutoResizeTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Auto Resized Text"
    android:textSize="500sp" /> <!-- maximum size -->

</LinearLayout>

Et le code Java :

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.RectF;
import android.os.Build;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.widget.TextView;

public class AutoResizeTextView extends TextView {
    private interface SizeTester {
        /**
         *
         * @param suggestedSize
         *            Size of text to be tested
         * @param availableSpace
         *            available space in which text must fit
         * @return an integer < 0 if after applying {@code suggestedSize} to
         *         text, it takes less space than {@code availableSpace}, > 0
         *         otherwise
         */
        public int onTestSize(int suggestedSize, RectF availableSpace);
    }

    private RectF mTextRect = new RectF();

    private RectF mAvailableSpaceRect;

    private SparseIntArray mTextCachedSizes;

    private TextPaint mPaint;

    private float mMaxTextSize;

    private float mSpacingMult = 1.0f;

    private float mSpacingAdd = 0.0f;

    private float mMinTextSize = 20;

    private int mWidthLimit;

    private static final int NO_LINE_LIMIT = -1;
    private int mMaxLines;

    private boolean mEnableSizeCache = true;
    private boolean mInitializedDimens;

    public AutoResizeTextView(Context context) {
        super(context);
        initialize();
    }

    public AutoResizeTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize();
    }

    public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialize();
    }

    private void initialize() {
        mPaint = new TextPaint(getPaint());
        mMaxTextSize = getTextSize();
        mAvailableSpaceRect = new RectF();
        mTextCachedSizes = new SparseIntArray();
        if (mMaxLines == 0) {
            // no value was assigned during construction
            mMaxLines = NO_LINE_LIMIT;
        }
    }

    @Override
    public void setTextSize(float size) {
        mMaxTextSize = size;
        mTextCachedSizes.clear();
        adjustTextSize();
    }

    @Override
    public void setMaxLines(int maxlines) {
        super.setMaxLines(maxlines);
        mMaxLines = maxlines;
        adjustTextSize();
    }

    public int getMaxLines() {
        return mMaxLines;
    }

    @Override
    public void setSingleLine() {
        super.setSingleLine();
        mMaxLines = 1;
        adjustTextSize();
    }

    @Override
    public void setSingleLine(boolean singleLine) {
        super.setSingleLine(singleLine);
        if (singleLine) {
            mMaxLines = 1;
        } else {
            mMaxLines = NO_LINE_LIMIT;
        }
        adjustTextSize();
    }

    @Override
    public void setLines(int lines) {
        super.setLines(lines);
        mMaxLines = lines;
        adjustTextSize();
    }

    @Override
    public void setTextSize(int unit, float size) {
        Context c = getContext();
        Resources r;

        if (c == null)
            r = Resources.getSystem();
        else
            r = c.getResources();
        mMaxTextSize = TypedValue.applyDimension(unit, size,
                r.getDisplayMetrics());
        mTextCachedSizes.clear();
        adjustTextSize();
    }

    @Override
    public void setLineSpacing(float add, float mult) {
        super.setLineSpacing(add, mult);
        mSpacingMult = mult;
        mSpacingAdd = add;
    }

    /**
     * Set the lower text size limit and invalidate the view
     *
     * @param minTextSize
     */
    public void setMinTextSize(float minTextSize) {
        mMinTextSize = minTextSize;
        adjustTextSize();
    }

    private void adjustTextSize() {
        if (!mInitializedDimens) {
            return;
        }
        int startSize = (int) mMinTextSize;
        int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom()
                - getCompoundPaddingTop();
        mWidthLimit = getMeasuredWidth() - getCompoundPaddingLeft()
                - getCompoundPaddingRight();
        mAvailableSpaceRect.right = mWidthLimit;
        mAvailableSpaceRect.bottom = heightLimit;
        super.setTextSize(
                TypedValue.COMPLEX_UNIT_PX,
                efficientTextSizeSearch(startSize, (int) mMaxTextSize,
                        mSizeTester, mAvailableSpaceRect));
    }

    private final SizeTester mSizeTester = new SizeTester() {
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public int onTestSize(int suggestedSize, RectF availableSPace) {
            mPaint.setTextSize(suggestedSize);
            String text = getText().toString();
            boolean singleline = getMaxLines() == 1;
            if (singleline) {
                mTextRect.bottom = mPaint.getFontSpacing();
                mTextRect.right = mPaint.measureText(text);
            } else {
                StaticLayout layout = new StaticLayout(text, mPaint,
                        mWidthLimit, Alignment.ALIGN_NORMAL, mSpacingMult,
                        mSpacingAdd, true);

                // Return early if we have more lines
                if (getMaxLines() != NO_LINE_LIMIT
                        && layout.getLineCount() > getMaxLines()) {
                    return 1;
                }
                mTextRect.bottom = layout.getHeight();
                int maxWidth = -1;
                for (int i = 0; i < layout.getLineCount(); i++) {
                    if (maxWidth < layout.getLineWidth(i)) {
                        maxWidth = (int) layout.getLineWidth(i);
                    }
                }
                mTextRect.right = maxWidth;
            }

            mTextRect.offsetTo(0, 0);
            if (availableSPace.contains(mTextRect)) {

                // May be too small, don't worry we will find the best match
                return -1;
            } else {
                // too big
                return 1;
            }
        }
    };

    /**
     * Enables or disables size caching, enabling it will improve performance
     * where you are animating a value inside TextView. This stores the font
     * size against getText().length() Be careful though while enabling it as 0
     * takes more space than 1 on some fonts and so on.
     *
     * @param enable
     *            Enable font size caching
     */
    public void enableSizeCache(boolean enable) {
        mEnableSizeCache = enable;
        mTextCachedSizes.clear();
        adjustTextSize(getText().toString());
    }

    private int efficientTextSizeSearch(int start, int end,
            SizeTester sizeTester, RectF availableSpace) {
        if (!mEnableSizeCache) {
            return binarySearch(start, end, sizeTester, availableSpace);
        }
        int key = getText().toString().length();
        int size = mTextCachedSizes.get(key);
        if (size != 0) {
            return size;
        }
        size = binarySearch(start, end, sizeTester, availableSpace);
        mTextCachedSizes.put(key, size);
        return size;
    }

    private static int binarySearch(int start, int end, SizeTester sizeTester,
            RectF availableSpace) {
        int lastBest = start;
        int lo = start;
        int hi = end - 1;
        int mid = 0;
        while (lo <= hi) {
            mid = (lo + hi) >>> 1;
            int midValCmp = sizeTester.onTestSize(mid, availableSpace);
            if (midValCmp < 0) {
                lastBest = lo;
                lo = mid + 1;
            } else if (midValCmp > 0) {
                hi = mid - 1;
                lastBest = hi;
            } else {
                return mid;
            }
        }
        // Make sure to return the last best.
        // This is what should always be returned.
        return lastBest;

    }

    @Override
    protected void onTextChanged(final CharSequence text, final int start,
            final int before, final int after) {
        super.onTextChanged(text, start, before, after);
        adjustTextSize();
    }

    @Override
    protected void onSizeChanged(int width, int height, int oldwidth,
            int oldheight) {
        mInitializedDimens = true;
        mTextCachedSizes.clear();
        super.onSizeChanged(width, height, oldwidth, oldheight);
        if (width != oldwidth || height != oldheight) {
            adjustTextSize();
        }
    }
}

Attention :

Méfiez-vous de cette résolu bogue dans Android 3.1 (Honeycomb) cependant.

0 votes

ok, j'ai testé le code, et il semble correct. cependant, vous avez utilisé getMaxLines() , qui est pour l'API 16, mais vous pouvez stocker le maxLines et l'obtenir en surchargeant setMaxLines et stocker sa valeur. je l'ai changé et maintenant il fonctionne bien. aussi, puisque parfois le texte pourrait être même trop long pour la plus petite taille, j'ai essayé d'utiliser setEllipsize, et cela a fonctionné aussi ! je pense que nous avons un gagnant. s'il vous plaît poster votre code ici afin que je puisse le marquer comme le bon.

0 votes

vous n'avez pas supprimé la fonction getMaxLines() et avez utilisé la vôtre. elle ne fonctionnera toujours qu'à partir de l'API16... veuillez la modifier pour que tout le monde puisse l'utiliser. je suggère de surcharger setMaxLines pour stocker le paramètre dans un champ et ensuite accéder au champ au lieu d'utiliser getMaxLines.

0 votes

vérifier maintenant, ajout du support pour les lignes maximales.

13voto

MartinH Points 51

J'ai modifié un peu la réponse de M-WaJeEh pour prendre en compte les éléments composites sur les côtés.

Le site getCompoundPaddingXXXX() méthodes de retour padding of the view + drawable space . Voir par exemple : TextView.getCompoundPaddingLeft()

Question : Cela fixe la mesure de la largeur et de la hauteur de l'espace du TextView disponible pour le texte. Si nous ne prenons pas en compte la taille du dessinable, elle est ignorée et le texte finira par chevaucher le dessinable.


Segment actualisé adjustTextSize(String) :

private void adjustTextSize(final String text) {
  if (!mInitialized) {
    return;
  }
  int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom() - getCompoundPaddingTop();
  mWidthLimit = getMeasuredWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();

  mAvailableSpaceRect.right = mWidthLimit;
  mAvailableSpaceRect.bottom = heightLimit;

  int maxTextSplits = text.split(" ").length;
  AutoResizeTextView.super.setMaxLines(Math.min(maxTextSplits, mMaxLines));

  super.setTextSize(
      TypedValue.COMPLEX_UNIT_PX,
      binarySearch((int) mMinTextSize, (int) mMaxTextSize,
                   mSizeTester, mAvailableSpaceRect));
}

0 votes

vous avez mis à jour la source de M-WaJeEh. pourquoi l'avoir mis comme une nouvelle réponse ? je sais que vous avez de la bonne volonté, mais est-ce une bonne chose de le mettre comme une réponse ? je ne suis pas sûr qu'il puisse voir que votre réponse...

1 votes

Je viens de m'inscrire pour pouvoir fournir cette mise à jour. Mon compte de réputation n'est que de 1 ce qui m'empêche de commenter des posts qui ne sont pas les miens (le minimum est de 15).

0 votes

Pas de soucis, peut-être voudriez-vous transmettre ma réponse à M-WajeEh car je ne peux même pas le contacter pour le moment :/.

8voto

avalancha Points 563

Ok, j'ai utilisé la dernière semaine pour réécrire massivement mon code pour précisément s'adapter à votre test. Vous pouvez maintenant le copier 1:1 et il fonctionnera immédiatement - y compris setSingleLine() . N'oubliez pas d'ajuster MIN_TEXT_SIZE et MAX_TEXT_SIZE si vous recherchez des valeurs extrêmes.

L'algorithme de convergence ressemble à ceci :

for (float testSize; (upperTextSize - lowerTextSize) > mThreshold;) {

    // Go to the mean value...
    testSize = (upperTextSize + lowerTextSize) / 2;

    // ... inflate the dummy TextView by setting a scaled textSize and the text...
    mTestView.setTextSize(TypedValue.COMPLEX_UNIT_SP, testSize / mScaledDensityFactor);
    mTestView.setText(text);

    // ... call measure to find the current values that the text WANTS to occupy
    mTestView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
    int tempHeight = mTestView.getMeasuredHeight();

    // ... decide whether those values are appropriate.
    if (tempHeight >= targetFieldHeight) {
        upperTextSize = testSize; // Font is too big, decrease upperSize
    }
    else {
        lowerTextSize = testSize; // Font is too small, increase lowerSize
    }
}

Et toute la classe peut se trouve ici.

Le résultat est très flexible maintenant. Cela fonctionne de la même manière que ce qui est déclaré en xml :

<com.example.myProject.AutoFitText
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="4"
    android:text="@string/LoremIpsum" />

... ainsi que construit de manière programmatique comme dans votre test.

J'espère vraiment que vous pourrez l'utiliser maintenant. Vous pouvez appeler setText(CharSequence text) maintenant pour l'utiliser d'ailleurs. La classe s'occupe d'exceptions incroyablement rares et devrait être solide comme un roc. La seule chose que l'algorithme fait pas de soutien est encore :

  • Appels à setMaxLines(x)x >= 2

Mais j'ai ajouté de nombreux commentaires pour vous aider à le construire si vous le souhaitez !


Veuillez noter :

Si vous l'utilisez normalement sans le limiter à une seule ligne, il peut y avoir des coupures de mots comme vous l'avez mentionné précédemment. Ceci est une fonctionnalité d'Android , pas la faute de la AutoFitText . Android cassera toujours les mots qui sont trop longs pour un TextView et c'est en fait assez pratique. Si vous souhaitez intervenir ici, veuillez consulter mes commentaires et mon code à partir de la ligne 203. J'ai déjà écrit une séparation adéquate et la reconnaissance pour vous, tout ce que vous aurez à faire dorénavant est de diviser les mots et ensuite de les modifier comme vous le souhaitez.

En conclusion : Vous devriez envisager de réécrire votre test pour qu'il prenne également en charge les caractères d'espacement, comme suit :

final Random _random = new Random();
final String ALLOWED_CHARACTERS = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
final int textLength = _random.nextInt(80) + 20;
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < textLength; ++i) {
    if (i % 7 == 0 && i != 0) {
        builder.append(" ");
    }
    builder.append(ALLOWED_CHARACTERS.charAt(_random.nextInt(ALLOWED_CHARACTERS.length())));
}
((AutoFitText) findViewById(R.id.textViewMessage)).setText(builder.toString());

Cela produira des résultats très beaux (et plus réalistes).
Vous trouverez également des commentaires pour vous aider à démarrer dans ce domaine.

Bonne chance et meilleures salutations

0 votes

il y a quelques problèmes, mais dans l'ensemble ça fonctionne donc bon travail. les problèmes : ne supporte pas les lignes multiples (comme vous l'avez écrit) et brisera le mot si vous essayez de le faire, inclut la fonction API16(addOnGlobalLayoutListener) qui je pense peut être totalement évitée (ou au moins utiliser OnPreDrawListener à la place), utilise la recherche binaire donc il peut tester des tailles qui ne conviennent pas du tout (et utiliser plus de mémoire sans raison, ce qui peut causer des exceptions si c'est trop grand), ne supporte pas la gestion quand quelque chose change (comme le texte lui-même).

0 votes

btw, vous ne devez pas utiliser la variable mTestView et faire les tests directement sur la vue courante, et de cette façon vous n'aurez pas à prendre en compte toutes les choses spéciales. aussi, je pense qu'au lieu de MAX_TEXT_SIZE vous pouvez utiliser le targetFieldHeight .

0 votes

je pense qu'au lieu d'une recherche binaire pure (surtout 2 d'entre elles), vous pouvez obtenir une meilleure estimation par le ratio de la cible par rapport à la taille mesurée. il y a aussi d'autres méthodes (newton et autre chose dont je ne me souviens pas) mais je ne pense pas qu'elles conviennent ici. celle que je suggère maintenant est meilleure puisque vous pouvez commencer à partir de la taille min au lieu de tester la taille max. le fait est que vous n'aurez pas besoin d'une taille max puisque vous continuez à faire une meilleure estimation.

3voto

Malachiasz Points 1537

Avertissement, bug dans Android 3 (Nid d'abeille) et Android 4.0 (Ice Cream Sandwich)

Les versions androïdes : 3.1 - 4.04 ont un bug, que setTextSize() à l'intérieur de TextView fonctionne seulement pour la première fois (première invocation).

Le bogue est décrit dans Problème 22493 : Bug de la hauteur des TextView sous Android 4.0 et Problème 17343 : la hauteur et le texte du bouton ne reviennent pas à leur état d'origine après l'augmentation et la diminution de la taille du texte sur HoneyComb. .

La solution de contournement consiste à ajouter un caractère de nouvelle ligne au texte attribué au TextView avant de modifier la taille :

final String DOUBLE_BYTE_SPACE = "\u3000";
textView.append(DOUBLE_BYTE_SPACE);

Je l'utilise dans mon code comme suit :

final String DOUBLE_BYTE_SPACE = "\u3000";
AutoResizeTextView textView = (AutoResizeTextView) view.findViewById(R.id.aTextView);
String fixString = "";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR1
   && android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {  
    fixString = DOUBLE_BYTE_SPACE;
}
textView.setText(fixString + "The text" + fixString);

J'ajoute ceci : " \u3000 "à gauche et à droite de mon texte, pour qu'il reste centré. Si vous l'avez aligné à gauche, ajoutez le caractère à droite seulement. Bien sûr, il est possible de l'intégrer avec le widget AutoResizeTextView, mais je voulais garder le code fixe à l'extérieur.

0 votes

pouvez-vous montrer exactement sur quelles lignes (avant/après quelles lignes) et dans quelle fonction ?

0 votes

ok merci. j'espère que cela résout tout, et que ceux qui liront ceci trouveront cela utile. actuellement je ne peux pas le vérifier. peut-être la prochaine fois que je l'utiliserai.

0 votes

Ce code est appelé depuis l'extérieur du code de la vue. Connaissez-vous peut-être une bonne alternative pour gérer cela à l'intérieur du code de la vue ?

1voto

Pnikosis Points 115

Convertissez la vue du texte en une image, et mettez l'image à l'échelle dans les limites.

Voici un exemple de la façon de convertir une vue en image : Convertir une vue en Bitmap sans l'afficher dans Android ?

Le problème est que votre texte ne sera pas sélectionnable, mais cela devrait faire l'affaire. Je n'ai pas essayé, donc je ne suis pas sûr de ce que cela donnerait (à cause de la mise à l'échelle).

0 votes

C'est une bonne idée, mais cela rendra également le texte pixelisé et supprimera toute fonctionnalité que je peux utiliser avec textView.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X