Проверьте, является ли textview эллипсисом в android - программирование

Проверьте, является ли textview эллипсисом в android

У меня TextView с шириной как wrap content. В этом TextView я устанавливаю текст, но текст не имеет одинаковой длины каждый раз. Когда текст очень длинный, я использую одиночную строку true и ellipsize: end. Но теперь у меня проблема. Я хочу установить видимость другого макета, но это зависит от длины моего текста. Если текст слишком длинный, чтобы поместиться на экране, я хочу установить значениеVisible true, но когда текст короткий и когда мне не нужна эллипсизация, я хочу установить видимость false. Поэтому мне нужно проверить статус моего TextView. Когда его эллипсис я хочу setVisible true, когда его не setVisible false. Как я могу это сделать. Это то, что я получил:

tvAle.post(new Runnable() {

        @Override
        public void run() {

            int lineCount    = tvAle.getLineCount();
            Paint paint =  new Paint();
            paint.setTextSize(tvAle.getTextSize());
            final float size = paint.measureText(tvAle.getText().toString());
            Log.v("a", ""+size+" "+tvAle.getWidth());
            if ((int)size > (tvAle.getWidth()+10)) {
                allergiesLayout.setVisibility(View.VISIBLE);
            }

            else
                allergiesLayout.setVisibility(View.GONE);

        }

но это решение не работает.

4b9b3361

Ответ 1

Вы можете использовать этот метод при условии: getEllipsisCount

Layout layout = textview1.getLayout();
if(layout != null) {
    int lines = layout.getLineCount();
    if(lines > 0) {
        int ellipsisCount = layout.getEllipsisCount(lines-1);
        if ( ellipsisCount > 0) {
            Log.d(TAG, "Text is ellipsized");
        } 
    } 
}

где строка может быть получена через getLineCount()

Ответ 2

Хорошо, принятое решение работает, но пропускает несколько угловых случаев, потому что оно проверяет только последнюю строку на наличие эллиптических символов. Если у нас есть TextView, состоящий из двух строк, и мы используем TruncateAt.START, чтобы обрезать текст в его начале, принятый ответ потерпит неудачу. : -/

Добавление ViewTreeObserver.OnPreDrawListener больше похоже на очень дорогие накладные расходы для меня. Поэтому я внес следующие улучшения в код принятого ответа:

/**
 * Checks if the text of the supplied {@link TextView} has been ellipsized.
 *
 * @param textView
 *         The {@link TextView} to check its text.
 *
 * @return {@code True} if the text of the supplied {@code textView} has been ellipsized.
 */
public static boolean isTextViewEllipsized(final TextView textView) {
    // Check if the supplied TextView is not null
    if (textView == null) {
        return false;
    }

    // Check if ellipsizing the text is enabled
    final TextUtils.TruncateAt truncateAt = textView.getEllipsize();
    if (truncateAt == null || TextUtils.TruncateAt.MARQUEE.equals(truncateAt)) {
        return false;
    }

    // Retrieve the layout in which the text is rendered
    final Layout layout = textView.getLayout();
    if (layout == null) {
        return false;
    }

    // Iterate all lines to search for ellipsized text
    for (int line = 0; line < layout.getLineCount(); ++line) {

        // Check if characters have been ellipsized away within this line of text
        if (layout.getEllipsisCount(line) > 0) {
            return true;
        }
    }

    return false;
}

Тем не менее, есть еще возможности для совершенствования. Но этот метод подходит для моих случаев использования. Исправления и улучшения приветствуются. :-)

Ответ 3

Использование getEllipsisCount не работает с текстом, в котором есть пустые строки. Я использовал следующий код, чтобы заставить его работать:

message.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {

            if(m.isEllipsized == -1) {
                Layout l = message.getLayout();
                if (message.getLineCount() > 5) {
                    m.isEllipsized = 1;
                    message.setMaxLines(5);
                    return false;
                } else {
                    m.isEllipsized = 0;
                }
            }
            return true;
        }
    });

Не забудьте установить maxLineCount в свой XML. Затем вы можете проверить строку в своем коде, и если она больше определенного числа, вы можете вернуть false, чтобы отменить рисование TextView и установить счетчик строк, а также флаг, чтобы сохранить слишком длинный текст или не. Текстовое изображение снова будет рисоваться с правильным количеством строк, и вы узнаете, его эллипсис или нет с флагом.

Затем вы можете использовать флаг isEllipsized для выполнения всех необходимых действий.