Android stackoverflow using while loop

I use this method to compress TextView text, as the name suggests:

 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; } 

And I have a stack overflow only with these devices (and sometimes this does not happen):

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

OS version: 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) 

I call this function inside TextWatcher afterTextChanged() , and yes, this may be a problem, but the idea is to reduce the size of the text when inserting it.

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

Examples of magazines:

Start typing letters (scroll to read the entire journal):

 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 

Start erasing the letters:

 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 ========================= 

What am I doing wrong and how can I improve this solution to prevent this exception?

+7
java android stack-overflow while-loop textwatcher
source share
2 answers

I found a solution, or so it seams, and it is rather strange and strange. So I noticed something strange, I was debugging (because the first time I could reproduce this error):

I noticed when the text was "green", the text was "well understood":

enter image description here enter image description here

but several times the text was not "green", especially if the text was a hundred as "... / ...":

enter image description here enter image description here


And that caused StackOverflow because TextUtils.ellipsize did not return, and the debugger also wandered a bit.

Change this:

 CharSequence text = textView.getText(); 

For this:

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

This is the solution.
And now it works. Thanks to IntelliJ for being the best of the IDE :)

+1
source share

I think you should do the math for the text and run your setTextSize once.

Even if you use some kind of temporary view to do the work, get the size from it. Instead of calling against a view using an eventlistener on it.

+1
source share

All Articles