我有textview,其中包含文本的一部分。当用户单击箭头时,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这样的动画属性。谁可以帮助我?
答案 0 :(得分:52)
您可以使用ObjectAnimator
ObjectAnimator animation = ObjectAnimator.ofInt(
tvText,
"maxLines",
25);
animation.setDuration(4000);
animation.start();
这会将“tvText”TextView的“maxLines”属性从最初设置的任何内容增加到25,在4000毫秒的时间内。
答案 1 :(得分:4)
虽然动画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。
答案 2 :(得分:1)
接受的答案根本就是错误的,因为它会强制调用 TextView.setMaxLines() lot 次,并且无理由地使用相同的值,使得生成的动画生涩
您可以使用带有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个整行,因此如果动画持续时间太长或者只影响几行,它仍然会显得生涩。最好的方法是创建自定义视图并进行适当的测量 onMeasure (参见例如https://github.com/Manabu-GT/ExpandableTextView)。
答案 3 :(得分:0)
所有其他解决方案对我来说效果都不理想。动画不连贯甚至闪烁。
我选择做的是设置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>