Android stackoverflow 使用 while 循环

Android stackoverflow using while loop

我正在使用此方法来缩小 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;
}

而且我只有这个设备有堆栈溢出(有时不会发生):

OS 版本: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 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    =========================

我哪里做错了,我该如何改进这个解决方案来防止这种异常?

我认为你应该计算一下 textsize,运行 你的 setTextSize 一次

即使您使用某种临时视图来完成工作,也要从中获取大小。而不是调用带有事件监听器的视图。

我已经找到了解决方案,或者它是接缝的,而且非常奇怪。所以我在调试时注意到一些奇怪的东西(因为这是我第一次重现这个错误):

我注意到文字是 "green" 文字是 "well parsed":

但有时文本不是 "green",特别是如果文本类似于“... / ...”:


这导致了 Whosebug,因为 TextUtils.ellipsize 没有返回并且调试器的行为也有点奇怪。

改变这个:

CharSequence text = textView.getText();

为此:

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

是解决方案。
现在它开始工作了。感谢 IntelliJ 成为有史以来最好的 IDE :)