tło
Wiele razy musimy automatycznie dopasować czcionkę TextView do podanych granic.
Problem
Niestety, chociaż istnieje wiele wątków i postów (i sugerowanych rozwiązań) mówiących o tym problemie (przykład tutaj , tutaj i tutaj ), żaden z nich tak naprawdę nie działa dobrze.
Dlatego postanowiłem przetestować każdy z nich, dopóki nie znajdę prawdziwej oferty.
Myślę, że wymagania takiego textView powinny być:
Powinny zezwalać na użycie dowolnej czcionki, kroju pisma, stylu i zestawu znaków.
Powinien obsługiwać zarówno szerokość, jak i wysokość
Nie obcinamy, chyba że tekst nie może się zmieścić z powodu ograniczenia, które mu daliśmy (przykład: zbyt długi tekst, zbyt mały dostępny rozmiar). Możemy jednak poprosić o poziomy / pionowy pasek przewijania, jeśli tylko chcemy, tylko w takich przypadkach.
Powinny zezwalać na wiele linii lub jedną linię. W przypadku wielu linii, zezwól na maksymalne i minimalne linie.
Nie powinno być powolne w obliczeniach. Używasz pętli do znalezienia najlepszego rozmiaru? Przynajmniej zoptymalizuj to i nie zwiększaj próbkowania o 1 za każdym razem.
W przypadku linii wieloliniowej należy zezwolić na zmianę rozmiaru lub użycie większej liczby linii i / lub pozwolić na samodzielne wybranie linii za pomocą znaku „\ n”.
Co próbowałem
Próbowałem tak wielu próbek (w tym tych linków, o których pisałem), a także próbowałem je zmodyfikować, aby obsługiwały przypadki, o których mówiłem, ale żadne z nich naprawdę nie działa.
Zrobiłem przykładowy projekt, który pozwala mi wizualnie sprawdzić, czy TextView automatycznie dopasowuje się poprawnie.
Obecnie mój przykładowy projekt losowo losuje tylko tekst (alfabet angielski plus cyfry) i rozmiar textView, i niech pozostanie z jedną linią, ale nawet to nie działa dobrze na żadnej próbce, której próbowałem.
Oto kod (dostępny również tutaj ):
Plik 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>
Plik 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();
}
}
Pytanie
Czy ktoś wie o rozwiązaniu tego powszechnego problemu, który faktycznie działa?
Nawet rozwiązanie, które ma o wiele mniej funkcji niż to, o czym pisałem, na przykład takie, które ma tylko stałą liczbę wierszy tekstu i dostosowuje czcionkę zgodnie z jego rozmiarem, ale nigdy nie ma dziwnych trzasków i zbyt dużej ilości tekstu duży / mały w porównaniu do dostępnej przestrzeni.
Projekt GitHub
Ponieważ jest to tak ważny TextView, postanowiłem opublikować bibliotekę, aby każdy mógł z niego łatwo korzystać i wnosić coś do tego tutaj .