Фон
Много раз нам нужно автоматически подгонять шрифт TextView к заданным границам.
Эта проблема
К сожалению, даже несмотря на то, что существует множество потоков и сообщений (и предлагаемых решений), в которых говорится об этой проблеме (пример здесь, здесь и здесь), ни один из них на самом деле не работает хорошо.
Поэтому я решил проверить каждый из них, пока не найду реальную сделку.
Я думаю, что требования от такого textView должны быть:
-
Должно позволять использовать любой шрифт, шрифт, стиль и набор символов.
-
Должен обрабатывать ширину и высоту
-
Нет усечения, если только текст не может уместиться из-за ограничений, которые мы ему дали (пример: слишком длинный текст, слишком маленький доступный размер). Тем не менее, мы можем запросить горизонтальную/вертикальную полосу прокрутки, если мы хотим, только для этих случаев.
-
Следует разрешить многострочное или однострочное. В случае многострочных, разрешите линии max и min.
-
Не должно быть медленным в вычислениях. Используя петлю для поиска лучшего размера? По крайней мере, оптимизируйте его и не увеличивайте выборку на 1 каждый раз.
-
В случае многострочного, следует разрешить предпочтение изменения размера или использования большего количества строк, и/или позволить самим выбирать строки, используя символ "\n".
Что я пробовал
Я перепробовал так много примеров (включая ссылки, о которых я писал), и я также попытался изменить их для обработки случаев, о которых я говорил, но ни один из них не работает.
Я сделал пример проекта, который позволяет мне визуально увидеть, правильно ли подходит TextView.
В настоящее время мой пример проекта только рандомизирует текст (английский алфавит плюс цифры) и размер textView, и позволяет ему оставаться с одной строкой, но даже это не работает на любом из примеров, которые я пробовал.
Вот код (также доступен здесь):
Файл 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>
Файл 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();
}
}
Вопрос
Кто-нибудь знает решение для этой общей проблемы, которая на самом деле работает?
Даже решение, которое имеет гораздо меньше возможностей, чем то, о чем я писал, например, решение, которое имеет только постоянное количество строк текста и корректирует свой шрифт в соответствии с его размером, но при этом никогда не имеет странных сбоев, а текст становится слишком большой/маленький по сравнению с его доступным пространством.
Проект GitHub
Поскольку это такой важный TextView, я решил опубликовать библиотеку, чтобы каждый мог легко использовать ее и внести свой вклад в нее здесь.