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

多行TextView右侧字符截断,但SharedElementTransition期间无此问题

问题:TextView右侧字符截断,且SharedElementReturnTransition后文本位置异常
  • 特定标准文本(无自定义字体/斜体)的MaterialTextView右侧字符被截断,例如“nitrosoethane”显示为“ntrosoethane”
  • 临时修复(设置文本阴影、自定义TextView)可解决截断,但SharedElementReturnTransition存在异常:返回调用Activity时,动画过程中文本换行位置正常,但动画结束后跳回截断状态,破坏过渡效果
  • 测量发现仅SharedElementEnterTransition时measuredWidth更大,其余参数(文本、字体、字号等)动画前后一致
  • 两个TextView均位于RecyclerView中,调用Activity的TextView的transitionName为动态设置

调用Activity的TextView布局

<com.google.android.material.textview.MaterialTextView
    android:id="@+id/name"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="32dp"
    android:layout_marginEnd="8dp"
    android:elevation="4dp"
    android:ellipsize="end"
    android:textColor="@color/text_primary"
    android:textSize="18sp"
    app:layout_constraintEnd_toStartOf="@+id/image"
    app:layout_constraintStart_toStartOf="@+id/card"
    app:layout_constraintTop_toBottomOf="@+id/formula"
    tools:text="Magnesium Chloride" />

目标Activity的TextView布局

<com.google.android.material.textview.MaterialTextView
    android:id="@+id/anim_name"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="32dp"
    android:layout_marginEnd="8dp"
    android:elevation="4dp"
    android:ellipsize="end"
    android:textColor="@color/text_primary"
    android:textSize="18sp"
    android:transitionName="@string/history_anim_name_tran"
    app:layout_constraintEnd_toStartOf="@+id/dummy_thumb"
    app:layout_constraintStart_toStartOf="@id/background"
    app:layout_constraintTop_toTopOf="@+id/name"
    tools:text="Magnesium Chloride" />

解决方案

1. 修复文本截断的根本问题

文本截断多由字符测量精度偏差或内边距计算异常导致,可尝试:

  • 给TextView添加微小的android:paddingEnd(如1dp),强制预留右侧空间:
    android:paddingEnd="1dp"
    
  • 禁用默认字体padding:
    android:includeFontPadding="false"
    
  • 若不需要省略号,替换android:ellipsize="end"为android:ellipsize="none",避免系统截断逻辑冲突

2. 解决SharedElementReturnTransition位置跳变

由于两个TextView分属不同RecyclerView,且动态设置transitionName,易出现视图状态不一致:

  • 对齐布局参数:检查两个TextView的父容器宽度、约束关系(当前调用方绑定card,目标绑定background,可能存在宽度差异),确保布局约束完全匹配
  • 返回时强制刷新视图:在调用Activity的onActivityReenter中触发TextView重新测量:
    override fun onActivityReenter(resultCode: Int, data: Intent?) {
        super.onActivityReenter(resultCode, data)
        val targetViewHolder = recyclerView.findViewHolderForAdapterPosition(targetPos) ?: return
        val textView = targetViewHolder.itemView.findViewById<MaterialTextView>(R.id.name)
        textView.post {
            textView.requestLayout()
            textView.invalidate()
        }
    }
    
  • 禁用过渡重叠:启动Activity时关闭返回过渡的重叠优化,避免状态冲突:
    val options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, textView, transitionName)
    val returnTransition = TransitionInflater.from(this).inflateTransition(R.transition.shared_element)
    returnTransition.setAllowReturnTransitionOverlap(false)
    WindowCompat.setSharedElementReturnTransition(window, returnTransition)
    startActivity(intent, options.toBundle())
    

3. RecyclerView复用问题处理

RecyclerView的item复用可能干扰过渡状态,可临时禁用目标item复用:

// 启动Activity前
val targetViewHolder = recyclerView.findViewHolderForAdapterPosition(targetPos)
targetViewHolder?.setIsRecyclable(false)

// 返回后恢复(如onResume中)
override fun onResume() {
    super.onResume()
    val targetViewHolder = recyclerView.findViewHolderForAdapterPosition(targetPos)
    targetViewHolder?.setIsRecyclable(true)
}

内容的提问来源于stack exchange,提问作者Michael P

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:30:42