Android stackoverflow с использованием цикла while

Я использую этот метод для сжатия текста TextView как это называется:

 public static float shrinkTextToFit(String caller, float availableWidth, TextView textView, float startingTextSize, float minimumTextSize) { startingTextSize = textView.getTextSize() < startingTextSize ? textView.getTextSize() : startingTextSize; Log.i("123", "========================="); Log.i("123", caller + " called shrinkTextToFit"); CharSequence text = textView.getText(); float textSize = startingTextSize; textView.setTextSize(startingTextSize); while (!TextUtils.equals(text, (TextUtils.ellipsize(text, textView.getPaint(), availableWidth, TextUtils.TruncateAt.END)))) { textSize -= 2; Log.i("123", "textSize: " + textSize); if ((textSize <= minimumTextSize) || (textSize <= 0)) { break; } else { textView.setTextSize(textSize); } } return textSize; } 

И у меня переполнение стека только с помощью этих устройств (а иногда и не бывает):

  • Samsung GT-I9192
  • Samsung GT-I9300
  • LG-D290

Версия ОС: 4.4.2, 4.3

 10 at android.widget.TextView.sendAfterTextChanged(TextView.java:8503) 11 at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:10633) 12 at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:970) 13 at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:497) 14 at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:247) 15 at android.text.TextUtils.ellipsize(TextUtils.java:1185) 16 at android.text.TextUtils.ellipsize(TextUtils.java:1079) 17 at android.text.TextUtils.ellipsize(TextUtils.java:1054) 18 at app.utils.Utils.float shrinkTextToFit(float,android.widget.TextView,float,float) 

Я TextWatcher эту функцию внутри TextWatcher afterTextChanged() и да, это может быть проблемой, но идея состоит в том, чтобы уменьшить размер текста при его вставке.

 @Override public void afterTextChanged(Editable s) { mEditText.removeTextChangedListener(mTextWatcher); Utils.shrinkTextToFit("watcher", mAvailableWidth, mEditText, 50, 10); mEditText.addTextChangedListener(mTextWatcher); } 

Примеры журналов:

Начните вводить буквы (прокрутите, чтобы прочитать весь журнал):

 08-01 14:48:50.284 watcher called shrinkTextToFit 08-01 14:48:50.676 ========================= 08-01 14:48:50.677 watcher called shrinkTextToFit 08-01 14:48:51.749 ========================= 08-01 14:48:51.749 watcher called shrinkTextToFit 08-01 14:48:51.749 textSize: 48.0 08-01 14:48:51.750 textSize: 46.0 08-01 14:48:51.751 textSize: 44.0 08-01 14:48:51.752 textSize: 42.0 08-01 14:48:52.500 ========================= 08-01 14:48:52.501 watcher called shrinkTextToFit 08-01 14:48:52.501 textSize: 48.0 08-01 14:48:52.501 textSize: 46.0 08-01 14:48:52.501 textSize: 44.0 08-01 14:48:52.501 textSize: 42.0 08-01 14:48:52.501 textSize: 40.0 08-01 14:48:52.503 textSize: 38.0 08-01 14:48:52.504 textSize: 36.0 08-01 14:48:53.013 ========================= 08-01 14:48:53.013 watcher called shrinkTextToFit 08-01 14:48:53.013 textSize: 48.0 08-01 14:48:53.013 textSize: 46.0 08-01 14:48:53.013 textSize: 44.0 08-01 14:48:53.014 textSize: 42.0 08-01 14:48:53.015 textSize: 40.0 08-01 14:48:53.015 textSize: 38.0 08-01 14:48:53.015 textSize: 36.0 08-01 14:48:53.016 textSize: 34.0 08-01 14:48:53.017 textSize: 32.0 08-01 14:48:53.020 textSize: 30.0 08-01 14:48:59.948 ========================= 08-01 14:48:59.949 watcher called shrinkTextToFit 08-01 14:48:59.949 textSize: 48.0 08-01 14:48:59.949 textSize: 46.0 08-01 14:48:59.949 textSize: 44.0 08-01 14:48:59.949 textSize: 42.0 08-01 14:48:59.950 textSize: 40.0 08-01 14:48:59.950 textSize: 38.0 08-01 14:48:59.950 textSize: 36.0 08-01 14:48:59.950 textSize: 34.0 08-01 14:48:59.951 textSize: 32.0 08-01 14:48:59.951 textSize: 30.0 08-01 14:48:59.951 textSize: 28.0 

Начните стирать буквы:

 08-01 14:48:59.953 ========================= 08-01 14:48:59.953 watcher called shrinkTextToFit 08-01 14:48:59.954 textSize: 48.0 08-01 14:48:59.954 textSize: 46.0 08-01 14:48:59.954 textSize: 44.0 08-01 14:48:59.954 textSize: 42.0 08-01 14:48:59.954 textSize: 40.0 08-01 14:48:59.954 textSize: 38.0 08-01 14:48:59.954 textSize: 36.0 08-01 14:48:59.954 textSize: 34.0 08-01 14:48:59.954 textSize: 32.0 08-01 14:48:59.954 textSize: 30.0 08-01 14:49:00.116 ========================= 08-01 14:49:00.116 watcher called shrinkTextToFit 08-01 14:49:00.116 textSize: 48.0 08-01 14:49:00.117 textSize: 46.0 08-01 14:49:00.117 textSize: 44.0 08-01 14:49:00.117 textSize: 42.0 08-01 14:49:00.117 textSize: 40.0 08-01 14:49:00.117 textSize: 38.0 08-01 14:49:00.117 textSize: 36.0 08-01 14:49:00.121 ========================= 08-01 14:49:00.121 watcher called shrinkTextToFit 08-01 14:49:00.121 textSize: 48.0 08-01 14:49:00.121 textSize: 46.0 08-01 14:49:00.121 textSize: 44.0 08-01 14:49:00.121 textSize: 42.0 08-01 14:49:00.284 ========================= 08-01 14:49:00.284 watcher called shrinkTextToFit 08-01 14:49:00.288 ========================= 08-01 14:49:00.288 watcher called shrinkTextToFit 08-01 14:49:00.444 ========================= 

Что я делаю неправильно и как я могу улучшить это решение, чтобы предотвратить это исключение?

Solutions Collecting From Web of "Android stackoverflow с использованием цикла while"

Я думаю, что вы должны сделать математику для создания текстов и запустить свой setTextSize один раз .

Даже если вы используете какой-то временный вид для выполнения работы, получите размер от этого. Вместо того, чтобы вызывать против него с помощью eventlistener.

Я нашел решение, или так оно швы, и это довольно странно и странно. Поэтому я заметил что-то странное, что я отлаживал (потому что в первый раз я мог воспроизвести эту ошибку):

Я заметил, когда текст был «зеленым», текст «хорошо разбирался»:

Введите описание изображения здесь Введите описание изображения здесь

Но несколько раз текст не был «зеленым», особенно если текст был созвучным как «… / …»:

Введите описание изображения здесь Введите описание изображения здесь

И это вызывало StackOverflow потому что TextUtils.ellipsize не возвращался, и отладчик тоже немного TextUtils.ellipsize .

Изменение этого:

 CharSequence text = textView.getText(); 

К этому:

 CharSequence text = textView.getText().toString(); 

Это решение.
И теперь он работает. Спасибо IntelliJ за то, что я лучший IDE когда-либо 🙂