在Android动画中如何缩放视图以适应内容大小?

4
我正在使用CardView作为Recycler Adapter的项目。一开始,所有的项目都不会显示全部内容(我剪切并用“... ...”代替),但是在点击后,被点击的项目将缩放其高度以适应内容高度。(在这里,我将文本设置为完整内容,并希望卡片可以缩放以适应它)看起来像这样:
我知道如何将高度动画化到特定的目标高度,但在这种情况下,我不知道如何测量需要显示全部内容的高度,每个项目应该有不同的目标高度。我该怎么做?

请确保您不使用maxlines属性或任何类似的属性。 - kulvinder
请查看此问题的答案(https://dev59.com/3GUo5IYBdhLWcg3w-zai)。 - karthik
@kulvinder,您的意思是使用maxlines的解决方案有一些缺点吗? - OOD Waterball
使用maxlines的缺点是无法平滑地动画显示多行文本,每次只能显示一行。此外,它仅适用于TextView。 - lelloman
2个回答

4
你可以要求 View 进行自我测量,不对其高度设置任何限制。请注意调用 view.getWidth() 方法,因为你是在 onClick() 方法中调用它的,所以只有在 View 被布局之后才能这样做。
int widthSpec = View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthSpec, heightSpec);
int targetHeight = view.getMeasuredHeight();

假设您的视图是具有以下属性设置的TextView:
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"

完整的示例代码如下:
// this is the height measured with maxLines 1 and height
// to wrap_content
final int startHeight = view.getHeight();

// you want to measure the TextView with all text lines
view.setMaxLines(Integer.MAX_VALUE);

int widthSpec = View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthSpec, heightSpec);

// final height of the TextView
int targetHeight = view.getMeasuredHeight();

// this is the value that will be animated from 0% to 100%
final int heightSpan = targetHeight-startHeight;

// remove that wrap_content and set the starting point
view.getLayoutParams().height = startHeight;
view.setLayoutParams(view.getLayoutParams());

Animation animation = new Animation(){
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        view.getLayoutParams().height = (int) (startHeight + heightSpan*interpolatedTime);
        view.setLayoutParams(view.getLayoutParams());
    }
};

animation.setDuration(1000);
view.startAnimation(animation);

是的,很酷的一点是你不仅可以在TextView上使用这种技术。 - lelloman

1
你可以非常简单地完成它。 当第一次将文本设置到TextView时,写入以下内容:
int minLineNumber = 2;
textView.setMaxLines(minLineNumber); // 2 is your number of line for the first time

并且当点击它时:

textView.setMaxLines(Integer.MAX_VALUE); // set the height like wrap_content

如果您想要动画效果,您需要像这样做:
ObjectAnimator animation = ObjectAnimator.ofInt(
        textView,
        "maxLines",
        textView.getLineCount());

int duration = (textView.getLineCount() - minLineNumber) * 50;
        animation.setDuration(duration);
        animation.start();

如果你的TextView中的文本过长,最好使用固定的持续时间,而不是依赖于高度。


但是,这会启动动画吗? - OOD Waterball
OOD Waterball,我用动画修改了答案。 - Ali_Ai_Dev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接