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

如何在ScrollView滚动时实现TextView文本大小动态调整动画

实现ScrollView滚动时TextView字号平滑缩放

问题说明

我有一个位于ScrollView外部的TextView,需求是:

  • 向下滚动ScrollView时,TextView字号逐渐缩小到最小15sp
  • 向上滚动时,字号恢复至初始的25sp

尝试过两种方法但效果不佳:

  1. 在ScrollListener的onScroll方法中每次调整0.01f字号,动画不流畅
  2. 使用setAutoSizeTextTypeUniformWithConfiguration(12,25, 2,TextView.AUTO_SIZE_TEXT_TYPE_UNIFORM),但该方法用于文本适配容器大小,不适合滚动驱动的字号变化,调整逻辑不符合需求

TextView布局代码:

<TextView
    android:id="@+id/t1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="10dp"
    android:fontFamily="@font/poppins"
    android:text="Some text"
    android:textColor="@color/black"
    android:textSize="25sp"
    android:textStyle="bold"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toBottomOf="@id/cons1"
/>

解决方案

核心思路是根据ScrollView的滚动比例,计算TextView的目标字号,通过比例映射+直接赋值实现流畅动画,避免逐帧微调的卡顿。

步骤1:实现滚动监听与字号计算

// 获取控件实例
ScrollView scrollView = findViewById(R.id.your_scroll_view);
TextView textView = findViewById(R.id.t1);

// 转换字号为px,避免屏幕密度差异导致的单位混乱
final float initialSizePx = getResources().getDimension(R.dimen.text_size_25sp);
final float minSizePx = getResources().getDimension(R.dimen.text_size_15sp);

// 监听ScrollView布局完成,确保能获取正确的滚动范围
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        scrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        // 计算可滚动总高度:内容高度 - ScrollView自身可见高度
        final int scrollRange = scrollView.getChildAt(0).getHeight() - scrollView.getHeight();
        
        scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                if (scrollRange <= 0) return;
                // 计算滚动比例,限制在0-1区间
                float scrollRatio = Math.max(0f, Math.min(1f, (float) scrollY / scrollRange));
                // 根据比例计算目标字号:初始值按比例递减到最小值
                float targetSizePx = initialSizePx - (initialSizePx - minSizePx) * scrollRatio;
                // 直接赋值,系统会自动处理绘制平滑度
                textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, targetSizePx);
            }
        });
    }
});

步骤2:添加统一管理的dimen资源(可选)

在res/values/dimens.xml中定义字号,方便后续修改:

<dimen name="text_size_25sp">25sp</dimen>
<dimen name="text_size_15sp">15sp</dimen>

关键注意事项

  • 不要在onScroll中逐帧微调字号(比如每次±0.01f),这种方式会触发频繁重绘,导致卡顿
  • setAutoSizeTextTypeUniformWithConfiguration是用于文本适配容器宽高的,和滚动驱动的字号变化逻辑不匹配,不适用此场景
  • 必须将sp转为px计算,避免不同屏幕密度下的显示偏差
  • 必须等待ScrollView布局完成后再计算滚动范围,否则获取的高度会不准确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:40:29