Contexte
Plusieurs fois, nous devons ajuster automatiquement la police de TextView aux limites qui lui sont données.
Le problème
Malheureusement, même s'il existe de nombreux fils et messages (et des solutions suggérées) parlant de ce problème (exemple ici , ici et ici ), aucun d'entre eux ne fonctionne vraiment bien.
C'est pourquoi, j'ai décidé de tester chacun d'eux jusqu'à ce que je trouve la vraie affaire.
Je pense que les exigences d'une telle textView devraient être:
Devrait permettre d'utiliser n'importe quelle police, police de caractères, style et jeu de caractères.
Devrait gérer à la fois la largeur et la hauteur
Pas de troncature à moins que le texte ne puisse pas tenir à cause de la limitation, nous l'avons donnée (exemple: texte trop long, taille disponible trop petite). Cependant, nous pourrions demander une barre de défilement horizontale / verticale si nous le souhaitons, juste pour ces cas.
Devrait autoriser plusieurs lignes ou une seule ligne. Dans le cas de plusieurs lignes, autorisez les lignes max et min.
Ne devrait pas être lent dans le calcul. Vous utilisez une boucle pour trouver la meilleure taille? Optimisez-le au moins et n'incrémentez pas votre échantillonnage de 1 à chaque fois.
Dans le cas de plusieurs lignes, devrait permettre de préférer le redimensionnement ou l'utilisation de plusieurs lignes, et / ou permettre de choisir les lignes nous-mêmes en utilisant le caractère "\ n".
Ce que j'ai essayé
J'ai essayé tellement d'échantillons (y compris ceux des liens dont j'ai parlé), et j'ai également essayé de les modifier pour gérer les cas, j'en ai parlé, mais aucun ne fonctionne vraiment.
J'ai fait un exemple de projet qui me permet de voir visuellement si le TextView s'adapte automatiquement correctement.
Actuellement, mon exemple de projet ne randomise que le texte (l'alphabet anglais plus les chiffres) et la taille du textView, et le laisse avec une seule ligne, mais même cela ne fonctionne pas bien sur aucun des é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 qui a juste un nombre constant de lignes de texte, et ajuste sa police en fonction de sa taille, mais n'a jamais de problèmes bizarres et d'avoir le texte trop grand / petit par rapport à son espace disponible.
Projet GitHub
Comme 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 .