Анимация MaxLines и эллипсизация

У меня есть textview, который содержит часть текста. Когда пользователь нажимает на стрелку, текстовое изображение изменяется, поэтому отображается полный текст. См. Приведенные ниже рисунки: collapsed

expanded

TextView имеет высоту wrap_content и при свертывании maxLines = "4".

OnClick стрелки содержит этот код:

        if (isExpanded) {
            btnToggle.setImageDrawable(getResources().getDrawable(
                    R.drawable.arrow_down));
            tvText.setMaxLines(4);
            tvText.setEllipsize(TruncateAt.END);
        } else {
            btnToggle.setImageDrawable(getResources().getDrawable(
                    R.drawable.arrow_up));
            tvText.setMaxLines(Integer.MAX_VALUE);
            tvText.setEllipsize(null);
        }
        isExpanded = !isExpanded;

Этот код работает, но он не анимирован. Мне нужно оживить расширение, поэтому TextView оживляет его на всю высоту. Я не могу найти ничего о анимации таких свойств, как MaxLines. Кто может мне помочь?

Ответы

Ответ 1

Вы можете достичь этого, используя ObjectAnimator

ObjectAnimator animation = ObjectAnimator.ofInt(
        tvText,
        "maxLines", 
        25);
animation.setDuration(4000);
animation.start();

Это увеличит свойство "maxLines" текстового текста "tvText" из того, что изначально установлено на 25, за период 4000 миллисекунд.

Подробнее здесь и здесь.

Ответ 2

В то время как анимация maxLines работает, результат немного прерывистый, так как высота вашего просмотра сильно перескакивает.

int startHeight = content.getMeasuredHeight();
content.setMaxLines(Integer.MAX_VALUE);
content.measure(
            View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.AT_MOST),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int endHeight = content.getMeasuredHeight();

content - это TextView с maxLines, установленным в 2. Теперь вы можете анимировать высоту TextView. Изменить: TextView прокручивает, когда он не может поместить его содержимое по вертикали, вам потребуются обходные пути. setMovementMethod(null) отключает прокрутку, но также отключает ссылку. Потому что Android.

Ответ 3

Принятый ответ в корне неверен, потому что он вызывает вызов TextView.setMaxLines() лотов раз с одинаковым значением без причины, что приводит к отрыву в результате анимации.

Вместо этого вы можете использовать простой ValueAnimator с флагом lastValue:

    ValueAnimator animator = ValueAnimator.ofInt(fromThisLineCount, toThisLineCount).setDuration(250);

    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        int lastValue = -1;

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            int value = (int) animation.getAnimatedValue();

            if (value == lastValue) {
                return;
            }

            lastValue = value;

            yourTextView.setMaxLines(value);
        }
    });

    animator.start();

Помните, что анимация добавляет/удаляет 1 целую строку каждый раз, поэтому она может все еще выглядеть отрывистой, если продолжительность анимации слишком высока или она затрагивает только несколько строк. Наилучший подход - создать пользовательский вид и выполнить соответствующие измерения onMeasure (см., Например, https://github.com/Manabu-GT/ExpandableTextView).