25

我有 textview 包含文本的一部分。当用户单击箭头时,文本视图会调整大小以显示全文。有关示例,请参见下图: 倒塌

展开

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 这样的动画属性的任何信息。谁能帮帮我?

4

4 回答 4

67

您可以使用ObjectAnimator

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

这将在 4000 毫秒期间将“tvText”TextView 的“maxLines”属性从最初设置的任何值增加到 25。

在此处此处查看更多信息。

于 2013-06-16T08:01:54.520 回答
5

在制作动画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设置为 2。现在您可以为高度maxLines设置动画。TextView编辑:TextView当它不能垂直适应它的内容时滚动,你需要解决方法。setMovementMethod(null)禁用滚动,但它也禁用链接点击。因为安卓。

于 2014-12-11T13:08:45.380 回答
3

接受的答案从根本上是错误的,因为它会无缘无故地以相同的值强制调用TextView.setMaxLines() 很多次,从而使生成的动画变得生涩。

您可以使用带有 lastValue 标志的简单 ValueAnimator :

    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 整行,因此如果动画持续时间太长或仅影响几行,它可能仍然看起来很生涩。最好的方法是创建一个自定义视图并在Measure上进行适当的测量(参见例如https://github.com/Manabu-GT/ExpandableTextView)。

于 2017-05-22T14:34:42.493 回答
1

所有其他解决方案都不适合我。动画断断续续,甚至闪烁。

我选择做的是 layoutParams 高度的动画。这个解决方案可能并不适合所有情况,但对我来说似乎效果很好。这是一个演示:

在此处输入图像描述

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val expectedWidthOfTextView = resources.displayMetrics.widthPixels
        val originalMaxLines = textView.maxLines
        if (originalMaxLines < 0 || originalMaxLines == Integer.MAX_VALUE)
            Log.d("AppLog", "already unbounded textView maxLines")
        else {
            textView.maxLines = Integer.MAX_VALUE
            textView.measure(
                View.MeasureSpec.makeMeasureSpec(expectedWidthOfTextView, View.MeasureSpec.AT_MOST),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            )
            val measuredLineCount = textView.lineCount
            val measuredTargetHeight = textView.measuredHeight
            Log.d("AppLog", "lines:$measuredLineCount/$originalMaxLines")
            textView.maxLines = originalMaxLines
            if (measuredLineCount <= originalMaxLines)
                Log.d("AppLog", "fit in original maxLines")
            else {
                Log.d("AppLog", "exceeded original maxLines")
                textView.setOnClickListener {
                    textView.setOnClickListener(null)
                    textView.maxLines = Integer.MAX_VALUE
                    val layoutParams = textView.layoutParams
                    val animation = ValueAnimator.ofInt(textView.height, measuredTargetHeight)
                    animation.addUpdateListener { valueAnimator ->
                        val value: Int = valueAnimator.animatedValue as Int
                        layoutParams.height = value
                        textView.requestLayout()
                    }
                    animation.start()
                    layoutParams.height = textView.height
                }
            }
        }

    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent" android:orientation="vertical" android:gravity="center_horizontal"
        android:layout_height="match_parent" android:animateLayoutChanges="true"
        tools:context=".MainActivity">

    <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"
               android:src="@android:drawable/sym_def_app_icon"/>

    <TextView
            android:id="@+id/textView" android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:ellipsize="end" android:maxLines="4" android:clickable="true" android:focusable="true"
            android:paddingEnd="16dp" android:paddingStart="16dp"
            android:textColor="#c1000000" android:textSize="14sp"
            android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."/>

    <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"
               android:src="@android:drawable/sym_def_app_icon"/>
</LinearLayout>
于 2018-11-05T09:30:30.367 回答