You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现TextView文本折叠时的LayoutTransition.CHANGING动画?

TextView折叠无动画问题的解决方案

问题说明

为评论场景实现「查看更多」功能时,TextView文本展开有动画效果,但折叠时无动画。尝试切换LayoutTransition类型未解决,需实现折叠时的平滑动画。

相关代码

Fragment代码

private var extended = false
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val testTextView = view.findViewById<TextView>(R.id.test_text)
    val container = view.findViewById<ConstraintLayout>(R.id.text_view_container)

    val comment = /* 长文本内容 */

    // 启用文本变化动画
    container.layoutTransition.enableTransitionType(
        LayoutTransition.CHANGING
    )

    if ((comment.length ?: 0) <= 200) {
        testTextView.text = comment
    } else {
        testTextView.text =
            comment.substring(
                0, if (comment.length < 200) comment.length else 200
            )
    }


    testTextView.setOnClickListener {
        extended = !extended
        if (extended) {
            testTextView.text = comment
        } else {
            testTextView.text = comment.substring(
                0, (if (comment.length < 200) comment.length else 200)
            )
        }
    }
}

XML代码

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment_blank_root"
    tools:context=".BlankFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/text_view_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/test_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="@string/hello_blank_fragment" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

解决思路与方案

问题根源

默认LayoutTransition.CHANGING动画仅处理视图尺寸增大的场景,折叠时的尺寸缩小未被触发;同时TextView设置layout_height="match_parent"会导致容器无法准确捕捉文本高度变化。

修复步骤

  1. 调整TextView布局参数
    将TextView的layout_height改为wrap_content,让高度随文本内容动态变化,确保容器能检测到高度改变:

    <TextView
        android:id="@+id/test_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_blank_fragment" />
    
  2. 手动触发过渡动画
    在修改文本前调用TransitionManager.beginDelayedTransition(container),强制系统捕捉视图变化并执行动画,替代仅依赖默认LayoutTransition的方式:

    testTextView.setOnClickListener {
        extended = !extended
        // 触发过渡动画
        TransitionManager.beginDelayedTransition(container)
        testTextView.text = if (extended) comment else comment.substring(0, 200)
    }
    
  3. 可选:自定义缩小动画
    如果需要更精细的动画控制,可自定义LayoutTransition添加尺寸缩小的Animator:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        val testTextView = view.findViewById<TextView>(R.id.test_text)
        val container = view.findViewById<ConstraintLayout>(R.id.text_view_container)
        val comment = /* 长文本内容 */
    
        // 自定义LayoutTransition
        val layoutTransition = LayoutTransition()
        // 保留原有增大动画
        layoutTransition.setAnimator(LayoutTransition.CHANGING, layoutTransition.getAnimator(LayoutTransition.CHANGING))
        // 添加缩小动画
        val shrinkAnimator = ValueAnimator.ofInt(0, 0)
        shrinkAnimator.addUpdateListener { animation ->
            val height = animation.animatedValue as Int
            testTextView.layoutParams.height = height
            testTextView.requestLayout()
        }
        layoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, shrinkAnimator)
        container.layoutTransition = layoutTransition
    
        // 初始化文本
        testTextView.text = if (comment.length <=200) comment else comment.substring(0,200)
    
        testTextView.setOnClickListener {
            extended = !extended
            TransitionManager.beginDelayedTransition(container)
            testTextView.text = if (extended) comment else comment.substring(0,200)
        }
    }
    

注意事项

  • 保留容器的android:animateLayoutChanges="true"属性,这是布局动画生效的基础。
  • 避免给TextView设置固定高度,否则高度变化无法被系统检测到。

内容的提问来源于stack exchange,提问作者Abed Sako

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:05:30