fundo
Muitas vezes, precisamos ajustar automaticamente a fonte do TextView aos limites dados a ele.
O problema
Infelizmente, embora existam muitos tópicos e postagens (e soluções sugeridas) falando sobre esse problema (exemplo aqui , aqui e aqui ), nenhum deles realmente funciona bem.
Por isso, decidi testar cada um deles até encontrar o negócio real.
Eu acho que os requisitos desse textView devem ser:
Deve permitir o uso de qualquer fonte, tipo de letra, estilo e conjunto de caracteres.
Deve lidar com largura e altura
Sem truncamento, a menos que o texto não possa caber devido à limitação que fornecemos (exemplo: texto muito longo, tamanho disponível muito pequeno). No entanto, poderíamos solicitar barra de rolagem horizontal / vertical, se desejarmos, apenas para esses casos.
Deve permitir várias linhas ou uma linha. No caso de várias linhas, permita linhas máxima e mínima.
Não deve ser lento no cálculo. Usando um loop para encontrar o melhor tamanho? Pelo menos, otimize-a e não aumente sua amostragem em 1 a cada vez.
No caso de várias linhas, deve-se preferir redimensionar ou usar mais linhas e / ou escolher as linhas usando o caractere "\ n".
O que eu tentei
Eu tentei tantas amostras (incluindo as dos links sobre os quais escrevi) e também tentei modificá-las para lidar com os casos de que já falei, mas nenhuma realmente funciona.
Fiz um projeto de amostra que me permite ver visualmente se o TextView se ajusta automaticamente.
Atualmente, meu projeto de amostra aleatoriamente apenas o texto (o alfabeto inglês mais dígitos) e o tamanho do textView, deixando-o com uma única linha, mas mesmo isso não funciona bem em nenhum dos exemplos que eu tentei.
Aqui está o código (também disponível aqui ):
Arquivo 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>
Arquivo 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();
}
}
A questão
Alguém sabe de uma solução para esse problema comum que realmente funciona?
Mesmo uma solução com muito menos recursos do que eu escrevi, por exemplo, que possui apenas um número constante de linhas de texto e ajusta sua fonte de acordo com seu tamanho, mas nunca apresenta falhas estranhas e o texto fica muito grande / pequeno em comparação com o espaço disponível.
Projeto GitHub
Como esse é um TextView tão importante, decidi publicar uma biblioteca, para que todos pudessem usá-lo facilmente e contribuir com ele aqui .