Задний план
Много раз нам нужно автоматически подгонять шрифт 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, я решил опубликовать библиотеку, чтобы каждый мог легко использовать ее и внести свой вклад в нее здесь .
источник
Ответы:
Благодаря простому затруднительного MartinH в здесь , этот код также заботится
android:drawableLeft
,android:drawableRight
,android:drawableTop
иandroid:drawableBottom
теги.Мой ответ здесь должен вас порадовать. Автоматическое масштабирование текста TextView, чтобы поместиться в пределах границ
Я изменил ваш тестовый пример:
Я размещаю код здесь по запросу разработчика Android :
Конечный эффект:
Пример файла макета:
И код Java:
Предупреждение:
Остерегайтесь этого решена ошибка в Android 3.1 (Honeycomb) , хотя.
источник
Я немного изменил ответ M-WaJeEh, чтобы учесть сложные рисунки по бокам.
Эти
getCompoundPaddingXXXX()
методы возвращаютpadding of the view + drawable space
. Смотрите, например: TextView.getCompoundPaddingLeft ()Проблема: это исправляет измерение ширины и высоты пространства TextView, доступного для текста. Если мы не принимаем во внимание размер рисования, он игнорируется, и текст в конечном итоге перекрывает рисунок.
Обновленный сегмент
adjustTextSize(String)
:источник
Хорошо, я использовал последнюю неделю, чтобы массово переписать свой код, чтобы он точно соответствовал вашему тесту. Теперь вы можете скопировать это 1: 1, и оно будет немедленно работать - в том числе
setSingleLine()
. Пожалуйста, не забудьте настроитьMIN_TEXT_SIZE
и,MAX_TEXT_SIZE
если вы собираетесь на крайние значения.Алгоритм конвергенции выглядит так:
И весь класс можно найти здесь.
Результат очень гибкий сейчас. Это работает так же, как объявлено в XML как:
... а также построен программно, как в вашем тесте.
Я действительно надеюсь, что вы можете использовать это сейчас. Вы можете позвонить
setText(CharSequence text)
сейчас, чтобы использовать его, кстати. Класс заботится о невероятно редких исключениях и должен быть твердым. Единственное, что алгоритм пока не поддерживает:setMaxLines(x)
кудаx >= 2
Но я добавил обширные комментарии, чтобы помочь вам построить это, если хотите!
Пожалуйста, обратите внимание:
Если вы просто используете это как обычно, не ограничивая его одной строкой, то может произойти разрыв слов, как вы уже упоминали ранее. Это функция Android , а не вина
AutoFitText
. Android всегда разбивает слова, которые слишком длинны для TextView, и это на самом деле довольно удобно. Если вы хотите вмешаться здесь, пожалуйста, смотрите мои комментарии и код, начинающийся со строки 203. Я уже написал адекватное разделение и признание для вас, все, что вам нужно будет сделать впредь, это разделить слова, а затем изменить, как вы хотите ,В заключение: вам следует подумать о переписывании теста, чтобы он также поддерживал пробелы, например:
Это даст очень красивые (и более реалистичные) результаты.
Вы найдете комментарии, чтобы вы начали в этом вопросе.
Удачи и наилучших пожеланий
источник
Мое требование заключается в
Я сослался на ссылку: Auto Scale TextView Text для размещения в границах (включая комментарии), а также DialogTitle.java
Я обнаружил, что предоставленное решение приятно и просто, но оно не изменяет динамически размер текстового поля. Это прекрасно работает, когда выбранная длина текста в представлении списка больше по размеру, чем существующая длина текста в
ScalableTextView
. Когда выделен текст, имеющий длину меньше, чем существующий текст вScalableTextView
, он не увеличивает размер текста, показывая текст в меньшем размере.Я изменил ScalableTextView.java, чтобы отрегулировать размер текста в зависимости от длины текста. Вот мой
ScalableTextView.java
Удачного кодирования ....
источник
Я объясню, как работает этот атрибут более низких версий Android, шаг за шагом:
1- Импорт библиотеки поддержки Android 26.xx в файл проекта. Если в IDE нет библиотеки поддержки, они будут загружены автоматически.
2- Откройте XML-файл макета и выполните рефакторинг, как этот тег вашего TextView. Этот сценарий: при увеличении размера шрифта в системе подгонка текста по доступной ширине, а не перенос слов.
источник
Предупреждение, ошибка в Android 3 (Honeycomb) и Android 4.0 (Ice Cream Sandwich)
Версии Android: 3.1-4.04 имеют ошибку, из-за которой setTextSize () внутри TextView работает только в первый раз (первый вызов).
Ошибка описана в выпуске 22493: ошибка высоты TextView в Android 4.0 и выпуск 17343: высота кнопки и текст не возвращаются в исходное состояние после увеличения и уменьшения размера текста в HoneyComb .
Обходной путь должен добавить символ новой строки к тексту, назначенному TextView перед изменением размера:
Я использую его в своем коде следующим образом:
Я добавляю этот символ «\ u3000» слева и справа от моего текста, чтобы держать его по центру. Если он выровнен по левому краю, то добавьте только справа. Конечно, он также может быть встроен в виджет AutoResizeTextView, но я хотел сохранить код исправления снаружи.
источник
Теперь есть официальное решение этой проблемы. Авторазмер TextViews, представленный в Android O, доступен в библиотеке поддержки 26 и обратно совместим вплоть до Android 4.0.
https://developer.android.com/preview/features/autosizing-textview.html
Я не уверен, почему https://stackoverflow.com/a/42940171/47680, который также включал эту информацию, был удален администратором.
источник
С июня 2018 года Android официально поддерживает эту функцию для Android 4.0 (уровень API 14) и выше.
С Android 8.0 (уровень API 26) и выше:
Версии Android до Android 8.0 (уровень API 26):
Проверьте мой подробный ответ .
источник
Преобразуйте текстовое представление в изображение, и масштабируйте изображение в пределах границ.
Вот пример того, как преобразовать представление в изображение: Преобразование представления в растровое изображение без его отображения в Android?
Проблема в том, что ваш текст не будет выделяться, но это должно сработать. Я не пробовал, поэтому не уверен, как это будет выглядеть (из-за масштабирования).
источник
Ниже приведено текстовое представление avalancha с добавленной функциональностью для пользовательских шрифтов.
Использование:
Не забудьте добавить: xmlns: foo = "http://schemas.android.com/apk/res-auto". Шрифт должен быть в активе фектории
Известные ошибки: не работает с Android 4.03 - шрифты невидимы или очень маленькие (оригинальная avalancha тоже не работает). Ниже приведено решение этой ошибки: https://stackoverflow.com/a/21851239/2075875
источник
Попробуй это
источник
Если вы ищете что-то проще:
источник
Быстрое решение проблемы, описанной @Malachiasz
Я исправил проблему, добавив настраиваемую поддержку для этого в классе автоматического изменения размера:
Просто позвоните
yourView.setTextCompat(newTextValue)
вместоyourView.setText(newTextValue)
источник
Попробуйте добавить
LayoutParams
иMaxWidth
иMaxHeight
кTextView
. Это заставит компоновку соблюдать родительский контейнер, а не переполнять.источник
Начиная с Android O, можно автоматически изменять размер текста в XML:
https://developer.android.com/preview/features/autosizing-textview.html
источник
После того, как я попробовал официальный Autosizing TextView для Android , я обнаружил, что ваша версия Android до Android 8.0 (уровень API 26), вам нужно использовать
android.support.v7.widget.AppCompatTextView
и убедиться, что ваша версия библиотеки поддержки выше 26.0.0. Пример:обновление :
Согласно ответу @ android-developer, я проверил
AppCompatActivity
исходный код и нашел эти две строки вonCreate
final AppCompatDelegate delegate = getDelegate(); delegate.installViewFactory();
и в
AppCompatDelegateImpl
хcreateView
это использует
AppCompatViewInflater
инфляционное представление, когдаAppCompatViewInflater
createView это будет использовать AppCompatTextView для "TextView".В моем проекте я не использую
AppCompatActivity
, поэтому мне нужно использовать<android.support.v7.widget.AppCompatTextView>
в XML.источник
AppCompatActivity
. AppCompatActivity использует макет инфлятора AppCompatViewInflater.