简体   繁体   中英

Android stackoverflow using while loop

I'm using this method to shrink TextView text as it's 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'm having a stack-overflow only with this devices (and some times it doesn't happen):

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

OS versions: 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'm calling this function inside TextWatcher afterTextChanged() and yes that could be the problem, but the idea is to shrink the text size while its being inserted.

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

Example Logs:

Start to type letters (scroll to read all the log):

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 to erase 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 exceptions?

I think you should do the math for textsize, and run your setTextSize one time .

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

I've found the solution, or so it seams, and it's quite odd and strange. So I've noticed something weird wile I was debugging (because for the first time I could reproduce this error):

I've noticed when the text was "green" the text was being "well parsed":

在此输入图像描述 在此输入图像描述

but some times the text wasn't "green", specially if the text was somenthing like "... / ...":

在此输入图像描述 在此输入图像描述


And that was causing the StackOverflow because TextUtils.ellipsize wasn't returning and the debugger was acting a bit strange too.

Changing this:

CharSequence text = textView.getText();

To this:

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

Is the solution.
And now it's working. Thanks IntelliJ for being the best IDE ever :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM