Antecedentes
Muchas veces necesitamos ajustar automáticamente la fuente de TextView a los límites establecidos.
El problema
Lamentablemente, a pesar de que hay muchos hilos y publicaciones (y soluciones sugeridas) que hablan sobre este problema (ejemplo aquí , aquí y aquí ), ninguno de ellos funciona realmente bien.
Por eso, he decidido probar cada uno de ellos hasta encontrar el verdadero negocio.
Creo que los requisitos de tal textView deberían ser:
Debe permitir el uso de cualquier fuente, tipo de letra, estilo y conjunto de caracteres.
Debe manejar tanto el ancho como la altura
Sin truncamiento a menos que el texto no se ajuste debido a la limitación que le hemos dado (ejemplo: texto demasiado largo, tamaño disponible demasiado pequeño). Sin embargo, podríamos solicitar una barra de desplazamiento horizontal / vertical si lo deseamos, solo para esos casos.
Debe permitir varias líneas o una sola línea. En caso de líneas múltiples, permita líneas máximas y mínimas.
No debe ser lento en el cálculo. ¿Usando un bucle para encontrar el mejor tamaño? Al menos optimícelo y no incremente su muestreo en 1 cada vez.
En el caso de líneas múltiples, debería permitir preferir cambiar el tamaño o usar más líneas, y / o permitir elegir las líneas nosotros mismos usando el carácter "\ n".
Lo que he intentado
He probado muchos ejemplos (incluidos los de los enlaces, sobre los que he escrito), y también he tratado de modificarlos para manejar los casos, he hablado, pero ninguno realmente funciona.
Hice un proyecto de muestra que me permite ver visualmente si TextView se ajusta automáticamente.
Actualmente, mi proyecto de muestra solo aleatoriza el texto (el alfabeto inglés más los dígitos) y el tamaño de textView, y lo dejo con una sola línea, pero incluso esto no funciona bien en ninguna de las muestras que he probado.
Aquí está el código (también disponible aquí ):
Expediente 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>
Expediente 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 pregunta
¿Alguien sabe de una solución para este problema común que realmente funcione?
Incluso una solución que tiene muchas menos características de las que he escrito, por ejemplo, una que solo tiene un número constante de líneas de texto, y ajusta su fuente de acuerdo con su tamaño, pero nunca tiene fallas extrañas y que el texto también grande / pequeño en comparación con su espacio disponible.
Proyecto GitHub
Dado que este es un TextView tan importante, he decidido publicar una biblioteca, para que todos puedan usarla fácilmente, y contribuir aquí .